【发布时间】:2017-05-09 05:09:21
【问题描述】:
为什么没有歧义?
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 &&。
上述方法非常适合转换构造函数(即一元构造函数)。但事实证明,对于更高的 arities,我必须明确地 = delete; 所有可能的组合组合,其中包含感兴趣参数的 const 右值引用版本(即 #if 1)。
然后我想:“为什么没有歧义?”——因为歧义还应该防止在上述情况下编译错误代码。
所以问题是:“为什么构造函数调用的混合情况没有歧义?”。
【问题讨论】:
-
B const &&不绑定到左值。对于a3,该构造函数根本不可行;同样a2。 -
@T.C.
B const &确实绑定到任何类型的右值。 -
是的,但不是相反。这就是重点。
-
B const &可以绑定到任何东西。B const &&只能绑定到右值。在存在右值的情况下,后者优于前者(在标准中找不到实际的子句,但我知道它在那里),因此没有歧义。 -
@T.C.和 NathanOliver:现在我明白了。
标签: c++ c++11 constructor c++14 rvalue-reference