This question is based on previous SO discussion (which was affected by non-compliant compilers). So I’m using the latest c++23 released versions of gcc/clang/MSVC.
Here is a simple test with conversion operator overloading, and passing it to a variant:
struct C
{
template <typename T> operator T () {return 0.5;}
operator int () {return 1;}
operator std::string () { return "";}
};
int main ()
{
C c;
std::cout << std::variant<int, double, std::string>{c}.index() << "n"; // selects template
std::cout << std::variant<int, std::string, double>{c}.index() << "n"; // selects template
// demand to use string, MSVC fails
std::cout << std::variant<int, std::string, double>{std::in_place_index<1>, c}.index() << "n";
}
I expected either the code to fail, because of ambiguity, or select type int
if variant
does index deduction in declaration order. But it always selects the template operator, no matter the order the types are mentioned in variant
. Are compilers correct? What’s the explanation? Or perhaps there an UB. Also is that a bug in MSVC failing to compile the last line?
Code Explorer Demo is here