std ::变体和模棱两可的初始化

发布于 2025-01-20 20:13:51 字数 515 浏览 0 评论 0原文

考虑以下代码:

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++ 规则,但这个示例显示了差异。对于这种行为有什么解释吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

宛菡 2025-01-27 20:13:51

P0608 之前,变体v{42.3} 42.3 以来也存在不明确的问题可以转换为 intlong double

P0608 更改了variant 构造函数的行为:

模板<类T> constexpr 变体(T&& t) noexcept(见下文);

  • Tj 为按如下方式确定的类型:为每个替代类型 Ti 构建一个虚函数 FUN(Ti) 其中 Ti x[] = {std::forward(t)}; 对于某些发明的变量 x 是格式良好的,并且,
    如果 Ticv bool,则 remove_cvref_t 为 bool。
    重载 FUN(Ti)
    由表达式的重载决策选择
    FUN(std::forward(t)) 定义了替代的 Tj 类型
    构建后包含的价值。

在您的示例中,variant有两种替代类型:intlong double,因此我们可以构建以下表达式

        int x[] = {std::forward<double>(42.3)}; // #1
long double y[] = {std::forward<double>(42.3)}; // #2

Since 只有 #2 格式良好变体成功推导出所包含值类型的类型长双精度

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 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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文