【问题标题】:Why const lvalue reference has priority over const rvalue reference during overloading resolution为什么在重载决议期间 const 左值引用优先于 const 右值引用
【发布时间】: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
}

这里我想将BC 实例的左值常量引用存储到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


【解决方案1】:

tl;dr:它是重新-这样设计的。

the original move proposal 下,您的代码会模棱两可。根据该提议,左值可以绑定到右值引用,但如果左值引用存在于重载集中,则更喜欢左值引用。

这个过程已经很晚了,随着越来越多的人开始理解该提案,并且仍在考虑 C++11 的概念,the rules were changed so that lvalues could not bind to rvalue references

我个人认为没有必要进行此更改,但 喜欢此更改的人多于不喜欢它的人,并且移动语义的基本功能可以以任何方式工作。所以这绝对是一个值得做出的妥协,而不是根本没有移动语义。

随着左值不能绑定到右值引用的变化,A(B const &&, C const &&) 不是重载决议集的一部分,如果 either 参数是左值。但是,如果其中一个(或两个)参数都是左值,A(B const &, C const &) 仍保留在重载集中。

【讨论】:

  • 如果const && 能够绑定所有与const & 相同的值类别,那么我认为问题将不复存在。当然,相应类别的匹配应该有优先权。
  • @Orient:你是对的。这是最初的搬家建议。 N2812在2009年改变了这一点。我认为现在扭转这种变化是不可行的。
  • const && 很少使用(例如 auto 关键字在 90' 和 10' 之间)。因此,如果const && 的含义会改变,但&& 的含义保留,那么(?)不会发生任何错误?只是一个虚构的案例。
  • 改变语言很难。如果您想尝试它,我不会将其击落(除非我找到了杀手锏)。但我不打算尝试。让移动语义标准化花了十年时间,而我已经没有太多的战斗力了。 ;-)
  • 感谢您的努力。我喜欢&&
猜你喜欢
  • 1970-01-01
  • 2017-03-26
  • 1970-01-01
  • 2017-04-15
  • 1970-01-01
  • 2021-12-22
  • 2017-04-13
  • 1970-01-01
  • 2020-01-23
相关资源
最近更新 更多