Allow implicit conversions in variant's operator=

Reuse the converting constructor's alternative-selection helper in
operator=(T&&). Select the best non-narrowing implicit conversion and
reject ambiguous matches.

Note that contrary to std::variant's operator=, no constraint is added
to refuse types T for which is_assignable_v<TAlternative&, T> is false.
Indeed, there are existing tests that explicitly check that operator=
can be used with a non-assignable type.
This commit is contained in:
Thomas Altenbach 2026-10-19 02:23:19 +02:00
parent bf525c947b
commit cba156b44f
2 changed files with 12 additions and 7 deletions

View File

@ -1266,17 +1266,15 @@ namespace etl
/// Move assignment operator for type.
///\param value The value to assign.
//***************************************************************************
template <
typename T,
etl::enable_if_t<!etl::is_same<etl::remove_cvref_t<T>, variant>::value && etl::is_one_of<etl::remove_cvref_t<T>, TTypes...>::value, int> = 0>
template < typename T, etl::enable_if_t<!etl::is_same<etl::remove_cvref_t<T>, variant>::value, int> = 0,
size_t AlternativeIndex = private_variant::select_alternative_index<T, TTypes...>::value,
typename TAlternative = type_from_index<AlternativeIndex>, etl::enable_if_t<etl::is_constructible<TAlternative, T>::value, int> = 0>
variant& operator=(T&& value)
{
using type = etl::remove_cvref_t<T>;
do_destroy();
do_construct<type>(etl::forward<T>(value));
do_construct<TAlternative>(etl::forward<T>(value));
type_id = index_of_type<type>::value;
type_id = AlternativeIndex;
return *this;
}

View File

@ -1468,12 +1468,19 @@ namespace
//*************************************************************************
TEST(test_assign_from_value)
{
// No conversion required
std::string text("Some Text");
test_variant_etl_3 variant_etl;
variant_etl = text;
CHECK_EQUAL(text, etl::get<std::string>(variant_etl));
// Conversion from float to double required
etl::variant<int, double> variant_double;
variant_double = 1.5f;
CHECK_EQUAL(1.5, etl::get<double>(variant_double));
}
//*************************************************************************