R. *_*des 38 c++ explicit-constructor initializer-list c++11
在C++标准§13.3.1.7[over.match.list]中,陈述如下:
在copy-list-initialization中,如果
explicit选择了构造函数,则初始化是错误的.
这就是为什么我们不能这样做的原因,例如:
struct foo {
// explicit because it can be called with one argument
explicit foo(std::string s, int x = 0);
private:
// ...
};
void f(foo x);
f({ "answer", 42 });
Run Code Online (Sandbox Code Playgroud)
(注意,这里发生的不是转换,即使构造函数是"隐式的"也不会是一个.这是一个foo对象直接使用它的构造函数初始化.除此之外std::string,这里没有转换.)
这对我来说似乎完全没问题.隐式转换不会让我感到困惑.
如果{ "answer", 42 }可以初始化其他东西,编译器不会背叛我并做错事:
struct bar {
// explicit because it can be called with one argument
explicit bar(std::string s, int x = 0);
private:
// ...
};
void f(foo x);
void f(bar x);
f({ "answer", 42 }); // error: ambiguous call
Run Code Online (Sandbox Code Playgroud)
没有问题:调用不明确,代码无法编译,我必须明确选择重载.
f(bar { "answer", 42 }); // ok
Run Code Online (Sandbox Code Playgroud)
由于明确规定禁令,我觉得我在这里遗漏了一些东西.据我所知,列表初始化选择显式构造函数对我来说似乎不是问题:通过使用列表初始化语法,程序员已经表达了进行某种"转换"的愿望.
怎么可能出错?我错过了什么?
Joh*_*itb 25
从概念上讲,复制列表初始化是将复合值转换为目标类型.提出措辞和解释理由的论文已经在"复制清单初始化"中考虑了"复制"一词,这是不幸的,因为它并没有真正传达其背后的实际理由.但它保持与现有措辞的兼容性.一{10, 20}对/元组值应不能够复制初始化String(int size, int reserve),因为字符串不是一对.
考虑显式构造函数但禁止使用.这在以下情况下是有意义的
struct String {
explicit String(int size);
String(char const *value);
};
String s = { 0 };
Run Code Online (Sandbox Code Playgroud)
0不传达字符串的值.因此,这会导致错误,因为两个构造函数都被考虑,但是explicit选择了构造函数,而不是将0其视为空指针常量.
不幸的是,这也发生在跨功能的重载解析中
void print(String s);
void print(std::vector<int> numbers);
int main() { print({10}); }
Run Code Online (Sandbox Code Playgroud)
由于含糊不清,这也是不正确的.在C++ 11之前发布的一些人(包括我)认为这是不幸的,但没有提出一篇论文提出有关这方面的改变(据我所知).
| 归档时间: |
|
| 查看次数: |
3926 次 |
| 最近记录: |