【问题标题】:universal reference vs const reference priority?通用参考与常量参考优先级?
【发布时间】:2013-08-16 02:20:59
【问题描述】:

当我考虑以下两个重载时:

template <class... T> void f(const T&... x);
template <class T> void f(const T& x);

我保证f(x) 将始终调用第二个函数并且永远不会导致歧义。从某种意义上说,对于一个论点,无论其类型是什么,第二个版本都比第一个版本普遍优先。

现在考虑一个函数有一个通用引用和一个常量引用版本的情况:

template <class T> void f(T&& x);
template <class T> void f(const T& x);

我的问题是:无论 x 的类型(r 值引用、引用、cv 限定符、指针...)如何,它们在这两个函数之间是否具有普遍的优先级,就像前一种情况一样? (如果是,优先级是什么?)

【问题讨论】:

标签: c++ templates c++11 reference universal-reference


【解决方案1】:

这两个函数之间没有统一的优先级。它们在重载解决算法中平等竞争。一般来说,所谓的“通用参考”获胜,除非const T&amp; 完全匹配,而const T&amp; 获胜。

struct A {};

int
main()
{
    f(std::declval<A>());  // calls f<A>(A&&), #1
    f(std::declval<const A>());  // calls f<const A>(const A&&), #1
    f(std::declval<A&>());  // calls f<A&>(A&), #1
    f(std::declval<A&&>());  // calls f<A>(A&&), #1
    f(std::declval<const A&&>());  // calls f<const A>(const A&&), #1
    f(std::declval<const A&>());  // calls f<A>(const A&), #2
}

好的建议是永远不要像这样超载。

【讨论】:

  • 可能值得一提的是,这些案例(如果有的话)#2 从来都不是一个候选者。
  • @BenVoigt 除非我遗漏了什么,否则这两种重载在所有这些表达式中都是可行的。
  • @aschepler:我认为你是对的。也许是 T&amp;&amp;T&amp; 最终令人惊讶。
  • 请注意,技术术语“精确匹配”(13.3.3.1.1)适用于所有十二个隐式转换序列。说“除非参数是const lvalue”可能更安全。
  • 我不确定,但f(std::declval&lt;const A&amp;&amp;&gt;()); 没有实际调用f&lt;const A&gt;(const A&amp;&amp;)
猜你喜欢
  • 2017-05-21
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多