From cba156b44fb4ea084805974f8ecc5833d184c325 Mon Sep 17 00:00:00 2001 From: Thomas Altenbach Date: Mon, 19 Oct 2026 02:23:19 +0200 Subject: [PATCH] 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 is false. Indeed, there are existing tests that explicitly check that operator= can be used with a non-assignable type. --- include/etl/private/variant_variadic.h | 12 +++++------- test/test_variant_variadic.cpp | 7 +++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/include/etl/private/variant_variadic.h b/include/etl/private/variant_variadic.h index 8e7670df..7b2ac4be 100644 --- a/include/etl/private/variant_variadic.h +++ b/include/etl/private/variant_variadic.h @@ -1266,17 +1266,15 @@ namespace etl /// Move assignment operator for type. ///\param value The value to assign. //*************************************************************************** - template < - typename T, - etl::enable_if_t, variant>::value && etl::is_one_of, TTypes...>::value, int> = 0> + template < typename T, etl::enable_if_t, variant>::value, int> = 0, + size_t AlternativeIndex = private_variant::select_alternative_index::value, + typename TAlternative = type_from_index, etl::enable_if_t::value, int> = 0> variant& operator=(T&& value) { - using type = etl::remove_cvref_t; - do_destroy(); - do_construct(etl::forward(value)); + do_construct(etl::forward(value)); - type_id = index_of_type::value; + type_id = AlternativeIndex; return *this; } diff --git a/test/test_variant_variadic.cpp b/test/test_variant_variadic.cpp index 8c8d6ac1..71881fd6 100644 --- a/test/test_variant_variadic.cpp +++ b/test/test_variant_variadic.cpp @@ -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(variant_etl)); + + // Conversion from float to double required + etl::variant variant_double; + variant_double = 1.5f; + + CHECK_EQUAL(1.5, etl::get(variant_double)); } //*************************************************************************