为什么当列表初始化有效时,带有转换构造函数的类型的复制初始化会失败? [重复]

问题描述 投票:0回答:2

考虑以下代码

// C++ 14.

struct A {
    A(int i) {}
};

struct B {
    B(A a) {}
};

int main(){
    A a = 5;
    B b1 = 5; // error
    B b2 = a;
    B b3 { 5 };
    B b4 = { 5 };
    return 0;
}

毫不奇怪,大多数初始化器都是有效的。但为什么第二个会出错呢?看起来 equal 初始化器只支持一级隐式转换?

这种行为在最新的 C++ 版本中仍然存在吗?

c++ initialization
2个回答
4
投票

您只能在隐式转换序列中执行最多一次用户定义的转换。除了第二行之外,所有行都遵循这一点。

A a = 5;
// okay, create an A from int

B b1 = 5;
// not okay, create an A from an int and then create a B from an A

B b2 = a;
// okay, create a B from an A

B b3 { 5 };
// okay, this is direct initialization of a B so 5 is allowed to be
// converted to an A and then that can be used to construct the B

B b4 = { 5 };
// okay, same as above except you are directly initializing a temporary

0
投票

失败的情况需要进行两次隐式转换。

  1. 5 通过使用其构造函数隐式转换为 A

  2. B 的构造函数被调用,将步骤 1 的结果作为参数传递

但是 C++ 最多需要一次隐式转换。

B b3 { 5 };

在这里,使用统一初始化语法算作显式构造,只进行一次隐式转换。

© www.soinside.com 2019 - 2024. All rights reserved.