为什么在使用初始化语法时不调用转换运算符,为什么 clang 错误消息看起来是错误的
Why is a conversion operator not called when using initialization syntax, and why does the clang error message seem wrong?
>我有以下代码,它使用显式转换构造函数构造一个对象 t2,该构造函数执行 t1 的隐式转换。这是意料之中的,并在第 3 版第 11.4.1 节的C++编程语言中进行了描述。
#include <iostream>
#include <string>
using namespace std;
class test1 {
public:
test1() {}
operator string() {
cout << "test1 string conversion operator called" << endl;
return string();
}
};
class test2 {
public:
test2() {}
test2(string s) {
cout << "test2 string conversion constructor called" << endl;
}
};
int main() {
test1 t1;
test2 t2(t1);
return 0;
}
正如您所期望的那样:
> clang++ --version
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.2
Thread model: posix
> clang++ -std=c++11 test.cc
> ./a.out
test1 string conversion operator called
test2 string conversion constructor called
但是,当将 t2 的构造更改为初始化语法时:
test1 t1;
test2 t2 = t1;
return 0;
Clang 输出以下内容:
test.cc:23:15: error: no viable conversion from 'test1' to 'test2'
test2 t2 = t1;
^ ~~
test.cc:13:11: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'test1' to 'const test2 &' for 1st argument
class test2 {
^
test.cc:13:11: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'test1' to 'test2 &&' for 1st argument
class test2 {
^
test.cc:16:9: note: candidate constructor not viable: no known conversion from 'test1' to 'string' (aka 'basic_string<char, char_traits<char>, allocator<char> >') for 1st argument
test2(string s) {
^
test.cc:8:9: note: candidate function
operator string() {
^
1 error generated.
我不知道初始化是否应该能够执行这样的隐式转换,但错误消息似乎非常非常错误。没有从"test1"到"string"的已知转换,但它甚至显示了候选函数运算符 string() {
什么给?C++标准对初始化构造函数中的隐式转换有什么看法?我假设这应该算作两次隐式转换,因此是不允许的,但编译器输出根本没有建议这样做。
首先,将test2::test2(string)
称为"显式转换构造函数"是错误的。它将用于隐式转换(如果您不想这样做,请将其标记为explicit
)。
无论如何,clang的错误消息是正确的,它几乎完美地解释了正在发生的事情。
这:
test2 t2(t1);
称为直接初始化。test2
的所有构造函数都是候选的,此外,编译器可以运行隐式转换序列来匹配参数。它找到了test1::operator string
和test2::test(string)
,一切都很好。
这:
test2 t2 = t1;
称为副本初始化。=
右侧的表达式需要转换为test2
,然后调用复制或移动构造函数来构造对象(至少在理论上,以后可以将其作为优化省略,但它必须可访问)。
相关文章:
- 我的字符计数代码计算错误.为什么
- C++ 错误 为什么这个矢量不输出?
- 当在函数调用中递增值时,程序正常工作,但是如果我们在单独的行中增加值而不是呼叫函数,则会出现错误.为什么
- 我正在将QPixmap传递给QAbstractButton::setIcon而不是QIcon,但我没有得到错误...为什么?
- 在 ZeroMQ 中绑定订阅者套接字并连接发布者套接字会在代码运行时给出错误.为什么
- 分段错误:为什么这里的数组索引越界了
- Box2D不寻常的错误.为什么 0阻止错误
- c++分段错误:为什么这个程序给出运行时错误(SIGSEGV)
- 链接列表错误 - 为什么头和尾引用指向相同地址
- VC++的一个大错误?为什么初始值设定项列表不对结构进行值初始化
- 分配大量内存会产生错误?为什么
- 得到一个段错误.为什么
- 变量名称与函数名称相同,导致编译器错误.为什么
- 访问在相应类的静态函数中创建的对象的私有成员变量不会导致错误.为什么?
- Qt5:此代码使用msvc2012编译正常,但使用MinGW编译时出现错误..为什么?
- 奇怪的错误-为什么编译器试图调用复制构造函数
- 我在使用 std::map 时收到此错误.为什么
- 我写了这个程序来反转链表中的元素,在编译这个程序后,在reverse()中显示错误.为什么
- Valgrind报告写入错误?为什么?
- 编译器错误 - 为什么我不能在Sublime Text 2中构建C++?