为什么没有歧义?
struct B {};
struct C {};
struct A
{
A(B const &, C const &) {}
A(B const &&, C const &&) = delete;
#if 0
A(B const &, C const &&) = delete;
A(B const &&, C const &) = delete;
#endif
};
B const b() { return {}; } // const result type may make sense
C const c() { return {}; } // for some user-defined types
int main()
{
A a0{B{}, C{}}; // I want to prohibit this
A a1{b(), c()}; // and this cases
B const bb{};
C const cc{};
A a2{b(), cc}; // But surely I also want to prohibit this
A a3{bb, c()}; // and this cases to compile
}
在这里,我想将对 B
和 C
实例的左值常量引用存储到 A
的实例中。当然,我想确保引用对象的生命周期超过 A
实例的生命周期。
为了实现这一点,我只是 = delete;
B const &&
和 C const &&
的重载,另外匹配 B &&
和C &&
对应。
上述方法非常适合转换构造函数(即一元构造函数)。但事实证明,对于更高的参数,我必须显式地 = delete;
所有组合上可能的组合,其中包含感兴趣参数的 const 右值引用版本(即 #if 1
).
然后我想:“为什么没有歧义?”,——因为在上述情况下歧义还应该防止编译错误代码。
所以问题是:“为什么构造函数调用的混合大小写没有歧义?”。
最佳答案
tl;dr:以这种方式重新设计。
下the original move proposal你的代码会模棱两可。根据该提案,左值可以绑定(bind)到右值引用,但如果它存在于重载集中,则更喜欢左值引用。
过程相当晚,因为越来越多的人开始理解该提案,并且仍在考虑 C++11 的概念,the rules were changed so that lvalues could not bind to rvalue references .
我个人并不认为这种改变是必要的,但是 喜欢这种改变的人比不喜欢它的人多得多,并且移动语义的基本功能可以以任何一种方式发挥作用。所以这绝对是一个值得做出的妥协,而不是根本没有移动语义。
由于左值不能绑定(bind)到右值引用,A(B const &&, C const &&)
不是重载决议集的一部分,如果任一个参数是一个左值。但是,如果其中一个(或两个)参数是左值,则 A(B const &, C const &)
仍保留在重载集中。
关于c++ - 为什么 const 左值引用在重载解析期间优先于 const 右值引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41302383/