【问题标题】:Reference collapsing and const [duplicate]参考折叠和 const [重复]
【发布时间】:2017-07-04 17:29:45
【问题描述】:

考虑这个程序:

template<typename T>
struct Foo
{
    void foo(const T&) {}   
    void foo(T&) {}
};


int main()
{
    Foo<double&> f;   
    double d = 3.14;
    f.foo(d);   //complains that foo() is ambigous
}

在上面,如果 Foo 被实例化为 Foo&lt;double&gt; ,那么一切都很好,但如果它被实例化为 Foo&lt;double&amp;&gt;,那么对 foo 的调用就会变得模棱两可。在推导 foo 的参数类型时,ref 是否在此处崩溃?如果是这样,为什么会忽略 constness?

【问题讨论】:

  • constness 被忽略是什么意思?你在哪里使用 constness ?
  • 好的,我在这里找到了答案 - stackoverflow.com/a/27728034/150365
  • @bolov 重复项似乎不相关。因为,在这种情况下,OP 指的是函数模板而不是类模板。
  • @101010 是的,但适用相同的规则/原则。无论如何,我不知道发生了什么,我现在看到问题已被 T.C. 关闭

标签: c++ c++14 type-deduction


【解决方案1】:

让我们看看如果我们尝试实例化 Foo 类模板会发生什么:

template<typename T>
struct Foo {
  void foo(T const&) {}   
  void foo(T&) {}
};

带有模板参数double&amp;。将 T 替换为 double&amp; 并根据参考折叠规则,您将得到:

struct Foo {
  void foo(double& const) {}   
  void foo(double&) {}
};

由于引用本质上是常量double&amp; const 等价于double&amp;。因此,您会得到以下实例:

struct Foo {
  void foo(double&) {}   
  void foo(double&) {}
};

编译器来了,大喊“老兄,你不能用相同的签名重载foo”。

CLANG 给出了一个更简洁的错误:

错误:'foo' 的多个重载实例化为相同的签名 'void (double &&)' void foo(T&) { }

Live Demo

【讨论】:

  • double&amp;,不是double&amp;&amp;
猜你喜欢
  • 2020-07-13
  • 1970-01-01
  • 2013-01-23
  • 1970-01-01
  • 2014-07-20
  • 1970-01-01
  • 2012-07-24
  • 2015-07-09
  • 1970-01-01
相关资源
最近更新 更多