gpt4 book ai didi

c++ - 如果声明了对类型的转换运算符和对类型的引用,为什么直接列表初始化会导致类型引用转换的歧义?

转载 作者:可可西里 更新时间:2023-11-01 16:09:26 27 4
gpt4 key购买 nike

问题出现在 this answer 的上下文中.

考虑一个例子:

struct foo {
int value;
operator int&(){ return value; }
operator int(){ return value; }
};

int main () {
int &a(foo{}); // #1
//int &b{foo{}}; // #2 -- ambiguity
int &c = foo{}; // #3
//int &d = {foo{}}; // #4-- ambiguity
int &d { a }; // #5
int &e = { a }; // #6
(void)a;
(void)c;
(void)d;
(void)e;
}

我不明白为什么 #2 和 #4 会导致歧义,而 #1 和 #3 不会。所以问题是 - 如果声明了对类型的转换运算符和对类型的引用,为什么直接列表初始化会导致隐式转换引用的歧义?

最佳答案

列表初始化,当用于初始化引用时,会将列出的值转换为纯右值(又名:临时值),用于直接初始化引用。

因此 int &b{foo{}} 在功能上等同于 int &b(int(foo{}))。这是模棱两可的;它可以通过 operator intoperator int& 生成 int

但即使它没有歧义,您仍然会得到一个对纯右值的非 const 左值引用。这是非法的。所以这段代码永远不会起作用。

Braced-init-lists(花括号)初始化对象,而不是对象的引用。如果您已经有一个对象并想获得对它的引用,请不要使用 braced-init-lists。


But in this case why does compiler accept #5?

因为列表初始化是一系列有优先级的规则。一个比我上面指出的规则具有更高优先级的规则是包含单个值的 braced-init-list 的情况,其类型与正在初始化的类型相同。 #5 和 6 正好符合这个要求,因为 dea 都是 int&

但是,如果您只是听取我的建议,而不是在不尝试创建对象时使用花括号初始化列表,那么您就不必担心这样的极端情况。

关于c++ - 如果声明了对类型的转换运算符和对类型的引用,为什么直接列表初始化会导致类型引用转换的歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41079111/

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