【发布时间】:2017-11-02 13:08:24
【问题描述】:
鉴于以下情况:
#include <stdio.h>
class X;
class Y
{
public:
Y() { printf(" 1\n"); } // 1
// operator X(); // 2
};
class X
{
public:
X(int) {}
X(const Y& rhs) { printf(" 3\n"); } // 3
X(Y&& rhs) { printf(" 4\n"); } // 4
};
// Y::operator X() { printf(" operator X() - 2\n"); return X{2}; }
int main()
{
Y y{}; // Calls (1)
printf("j\n");
X j{y}; // Calls (3)
printf("k\n");
X k = {y}; // Calls (3)
printf("m\n");
X m = y; // Calls (3)
printf("n\n");
X n(y); // Calls (3)
return 0;
}
到目前为止,一切都很好。现在,如果我启用转换运算符Y::operator X(),我会得到这个;-
X m = y; // Calls (2)
我的理解是,发生这种情况是因为 (2) 比 (3) 的“更少 const”,并且
因此首选。省略了对 X 构造函数的调用
我的问题是,为什么 X k = {y} 的定义没有以同样的方式改变其行为?我知道= {} 在技术上是“列表复制初始化”,但是在没有采用initializer_list 类型的构造函数的情况下,这不会恢复为“复制初始化”行为吗?即 - 与X m = y 相同
我的理解的漏洞在哪里?
【问题讨论】:
-
对不起 - 我搞砸了最小化代码 - 已更正(希望如此)
-
使用了 Exaxt 编译器?我知道在某些编译器中与此相邻的代码不一致。
-
改进了示例。我已经在 11、14 和 17 模式下使用 cppreference.com(clang 3.8)上的编译器工具进行了尝试。结果是一样的
-
感谢大家的帮助和全面的回答。我想我明白现在发生了什么。但我必须同意 Barry 的观点——C++ 初始化太疯狂了! :-)
标签: c++ c++11 c++14 list-initialization copy-initialization