为什么没有歧义?
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
实例的左值const引用存储到A
的实例中。当然,我想确保,引用对象的生命周期克服了A
实例的生命周期。
要实现此目的,= delete;
和B const &&
只会C const &&
重叠,此外还会匹配B &&
和C &&
。
上述方法适用于转换构造函数(即一元函数)。但事实证明,对于更高的灵魂,我必须明确= delete;
所有组合可能的组合,其中包含感兴趣的参数的常量参考版本(即#if 1
)。
然后我想:"为什么没有含糊不清?", - 因为在上述情况下,歧义也应该阻止编译错误的代码。
所以问题是:"为什么对于构造函数调用的混合情况没有歧义?"。
答案 0 :(得分:5)
tl; dr:重新 - 这样设计。
在the original move proposal下,您的代码不明确。根据该提议,lvalues 可以绑定到右值引用,但如果它存在于重载集中,则更喜欢左值引用。
在此过程中相当晚,随着越来越多的人开始理解该提案,并且正在考虑C ++ 11的概念,the rules were changed so that lvalues could not bind to rvalue references。
我个人并不觉得这种变化是必要的,但远更多人喜欢这种变化而不喜欢它,移动语义的基本功能无论如何都会起作用。所以这绝对是一个值得做出的妥协,而不是完全没有移动语义。
如果 参数是左值,则lvalues无法绑定到右值引用的更改,A(B const &&, C const &&)
不是重载决策集的一部分。但是,如果任一(或两个)参数都是左值,则A(B const &, C const &)
仍保留在重载集中。