std::variant 和模棱两可的初始化
std::variant and ambiguous initialization
考虑以下代码:
void fnc(int)
{
std::cout << "int";
}
void fnc(long double)
{
std::cout << "long double";
}
int main()
{
fnc(42.3); // error
}
由于对 fnc
.
的模糊调用,它给出了一个错误
但是,如果我们写下一段代码:
std::variant<int, long double> v{42.3};
std::cout << v.index();
输出为1
,表明选择了double
->long double
转换。
据我所知,std::variant
遵循关于转换等级的 C++ 规则,但这个例子显示了不同之处。对这种行为有什么解释吗?
在P0608, variant<int, long double> v{42.3}
also has the ambiguous issue之前,因为42.3
可以转换为int
或long double
。
P0608 已更改 the behavior of variant
's constructors:
template<class T> constexpr variant(T&& t) noexcept(see below);
- Let
Tj
be a type that is determined as follows: build an imaginary function FUN(Ti)
for each alternative type Ti
for which Ti x[] = {std::forward<T>(t)};
is well-formed for some invented variable x
and,
if Ti
is cv bool
, remove_cvref_t<T>
is bool. The overload FUN(Ti)
selected by overload resolution for the expression
FUN(std::forward<T>(t))
defines the alternative Tj
which is the type
of the contained value after construction.
在您的示例中,variant
有两种替代类型:int
和 long double
,因此我们可以构建以下表达式
int x[] = {std::forward<double>(42.3)}; // #1
long double y[] = {std::forward<double>(42.3)}; // #2
由于only #2
is well-formed,variant
成功推导出包含的值类型long double
。
考虑以下代码:
void fnc(int)
{
std::cout << "int";
}
void fnc(long double)
{
std::cout << "long double";
}
int main()
{
fnc(42.3); // error
}
由于对 fnc
.
的模糊调用,它给出了一个错误
但是,如果我们写下一段代码:
std::variant<int, long double> v{42.3};
std::cout << v.index();
输出为1
,表明选择了double
->long double
转换。
据我所知,std::variant
遵循关于转换等级的 C++ 规则,但这个例子显示了不同之处。对这种行为有什么解释吗?
在P0608, variant<int, long double> v{42.3}
also has the ambiguous issue之前,因为42.3
可以转换为int
或long double
。
P0608 已更改 the behavior of variant
's constructors:
template<class T> constexpr variant(T&& t) noexcept(see below);
- Let
Tj
be a type that is determined as follows: build an imaginary functionFUN(Ti)
for each alternative typeTi
for whichTi x[] = {std::forward<T>(t)};
is well-formed for some invented variablex
and, ifTi
iscv bool
,remove_cvref_t<T>
is bool. The overloadFUN(Ti)
selected by overload resolution for the expressionFUN(std::forward<T>(t))
defines the alternativeTj
which is the type of the contained value after construction.
在您的示例中,variant
有两种替代类型:int
和 long double
,因此我们可以构建以下表达式
int x[] = {std::forward<double>(42.3)}; // #1
long double y[] = {std::forward<double>(42.3)}; // #2
由于only #2
is well-formed,variant
成功推导出包含的值类型long double
。