gpt4 book ai didi

c++ - 如果复制列表初始化允许显式构造函数会出现什么问题?

转载 作者:IT老高 更新时间:2023-10-28 12:31:20 26 4
gpt4 key购买 nike

在 C++ 标准 §13.3.1.7 [over.match.list] 中,声明如下:

In copy-list-initialization, if an explicit constructor is chosen, the initialization is ill-formed.

这就是为什么我们不能这样做的原因,例如:

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 });

(请注意,这里发生的情况不是转换,即使构造函数是“隐式”的,它也不会是一个转换。这是使用它的 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

没问题:调用不明确,代码无法编译,我必须明确选择重载。

f(bar { "answer", 42 }); // ok

由于明确规定了禁令,我觉得我在这里遗漏了一些东西。据我所知,列表初始化选择显式构造函数对我来说似乎不是问题:通过使用列表初始化语法,程序员已经表达了进行某种“转换”的愿望。

会出什么问题?我错过了什么?

最佳答案

从概念上讲,复制列表初始化是将复合值转换为目标类型。提出措辞和解释理由的论文已经认为“复制列表初始化”中的“复制”一词是不幸的,因为它并没有真正传达其背后的实际理由。但保留它是为了与现有措辞兼容。 {10, 20} 对/元组值不应该能够复制初始化 String(int size, int reserve),因为字符串不是对。

考虑使用显式构造函数,但禁止使用。这在以下情况下是有意义的

struct String {
explicit String(int size);
String(char const *value);
};

String s = { 0 };

0 不传达字符串的值。所以这会导致错误,因为考虑了 both 构造函数,但选择了 explicit 构造函数,而不是将 0 视为空指针持续的。

不幸的是,这也发生在跨函数的重载决议中

void print(String s);
void print(std::vector<int> numbers);

int main() { print({10}); }

由于模棱两可,这也是格式错误的。在 C++11 发布之前,有些人(包括我)认为这很不幸,但没有提出对此提出更改的论文(据我所知)。

关于c++ - 如果复制列表初始化允许显式构造函数会出现什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9157041/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com