'std::variant and ambiguous initialization
Consider the following code:
void fnc(int)
{
std::cout << "int";
}
void fnc(long double)
{
std::cout << "long double";
}
int main()
{
fnc(42.3); // error
}
It gives an error because of an ambiguous call to fnc.
However, if we write the next code:
std::variant<int, long double> v{42.3};
std::cout << v.index();
the output is 1, which demonstrates that the double->long double conversion has been chosen.
As far as I know, std::variant follows the C++ rules about conversion ranks, but this example shows the difference. Is there any explanation for such a behavior?
Solution 1:[1]
Before P0608, variant<int, long double> v{42.3} also has the ambiguous issue since 42.3 can be converted to int or long double.
P0608 changed the behavior of variant's constructors:
template<class T> constexpr variant(T&& t) noexcept(see below);
- Let
Tjbe a type that is determined as follows: build an imaginary functionFUN(Ti)for each alternative typeTifor whichTi x[] = {std::forward<T>(t)};is well-formed for some invented variablexand, ifTiiscv bool,remove_cvref_t<T>is bool. The overloadFUN(Ti)selected by overload resolution for the expressionFUN(std::forward<T>(t))defines the alternativeTjwhich is the type of the contained value after construction.
In your example, the variant has two alternative types: int and long double, so we can build the following expression
int x[] = {std::forward<double>(42.3)}; // #1
long double y[] = {std::forward<double>(42.3)}; // #2
Since only #2 is well-formed, the variant successfully deduces the type of the contained value type long double.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
