pet*_*ter 4 c++ clang implicit-conversion copy-initialization c++11
我有以下代码,它使用显式转换构造函数构造一个对象 t2,该构造函数执行 t1 的隐式转换。这是预期的,并在 C++ 编程语言的第 3 版第 11.4.1 节中进行了描述。
#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;
}
Run Code Online (Sandbox Code Playgroud)
正如你所期望的:
> 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
Run Code Online (Sandbox Code Playgroud)
但是,将 t2 的构造更改为初始化语法时:
test1 t1;
test2 t2 = t1;
return 0;
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
我不知道初始化是否应该能够执行这样的隐式转换,但是错误消息似乎非常非常错误。没有已知的从 'test1' 到 'string' 的转换,但它甚至显示了候选函数 operator string() {
是什么赋予了?C++ 标准对初始化构造函数中的隐式转换有什么看法?我认为这应该算作两次隐式转换,因此是不允许的,但编译器输出根本不建议这样做。
首先,它是错叫test2::test2(string)一个“显式转换构造函数”。它将用于隐式转换(explicit如果您不想要,请标记它)。
无论如何,clang 的错误信息是正确的,它几乎完美地解释了正在发生的事情。
这个:
test2 t2(t1);
Run Code Online (Sandbox Code Playgroud)
称为直接初始化。的所有构造函数test2都是候选者,此外,编译器可以运行隐式转换序列来匹配参数。它发现test1::operator string并且test2::test(string)一切都很好。
这个:
test2 t2 = t1;
Run Code Online (Sandbox Code Playgroud)
称为复制初始化。右侧的表达式=需要转换为test2,然后将调用复制或移动构造函数来构造对象(至少在理论上,以后可以将其作为优化省略,但它必须是可访问的) .
| 归档时间: |
|
| 查看次数: |
4025 次 |
| 最近记录: |