为什么这种直接初始化有效?(C++17)
Why is this direct initialization valid? (C++ 17)
考虑以下两个类:
class B
{
public:
B() { }
B(const B& b) = delete; //Move ctor not implicitly declared
};
class A
{
public:
A() { }
operator B()
{
return B();
}
};
我可以看到为什么这段代码编译得很好:
A a;
B b = a;
遵循复制初始化的规则,对象"a"被转换为 B 类型的 prvalue,并且在 C++17 中不再需要复制构造函数,因此没有错误:
如果 T 是类类型,并且 cv 非限定版本的类型 其他不是 T 或派生自 T,或者如果 T 是非类类型,而是 其他类型是类类型,用户定义的转换序列 可以从 other 的类型转换为 T(或从 T 派生的类型( 如果 T 是类类型并且转换函数可用(是 检查并通过重载分辨率选择最佳一个。这 转换的结果,这是一个临时值(直到 C++17(prvalue 表达式(自 C++17 起(,如果转换构造函数是 used,然后用于直接初始化对象。最后一步是 通常优化出来并构建转换结果 直接在为目标对象分配的内存中,但是 需要适当的构造函数(移动或复制(才能访问 即使它没有被使用。(至C++17(
但是,为什么这种直接列表初始化也可以编译?
A a;
B b{ a };
我在列表初始化中找不到任何措辞,说明在这种情况下编译器应该尝试将 A 转换为 B。仅考虑构造函数上的重载解析:
如果前一阶段未产生匹配项,则 T 的所有构造函数 参与针对以下参数集的重载解析 由大括号初始化列表的元素组成,但有限制 只允许非缩小范围的转换
但是在这种情况下,复制构造函数被删除,所以不应该通过重载解析来选择它吗?
这是CWG 2327。就标准而言,您是正确的,但是一些编译器也在此上下文中考虑了转换函数 - 因为它确实有意义。
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 欧拉项目#8答案是大以获得有效答案
- 如何在c++17中制作一个模板包装器/装饰器
- 调整大小后指向元素值的指针unordered_map有效?
- 枚举环境变量的惯用C++14/C++17方法
- 为什么是0;C++中的有效语句
- 最高有效数字侧的第N位
- gcc和c++17的过载解析失败
- 数据成员SFINAE的C++17测试:gcc vs clang
- GCC对可能有效的代码抛出init list生存期警告
- 有效地使用std::unordered_map来插入或增加键的值
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- C++17中的并行执行策略
- c++中O(n^(1/3))中一个数的除数的有效计数
- 为什么这种直接初始化有效?(C++17)
- 使用C 17处理Unicode的有效,符合标准的机制是什么
- 字符串构造函数将两个字符* 放入另一个 std::string 在 C++14 中有效,但不适用于 C++17
- 自 C++17 年以来,具有正确地址和类型的指针始终是有效的指针
- C++17 有效地将参数包参数与 std::array 元素相乘
- 如何有效地将8个17位整数转换为17个8位整数