【问题标题】:Isn't `void f(A<0>, tuple<T *...>)` more specialized than `void f(A<I>, tuple<T *...>)`?`void f(A<0>, tuple<T *...>)` 不是比 `void f(A<I>, tuple<T *...>)` 更专业吗?
【发布时间】:2015-11-08 14:27:47
【问题描述】:
#include <tuple>

template<int I>
struct A {};

template<int I, typename... T>
void f(A<I>, std::tuple<T *...>) {}

template<typename... T>
void f(A<0>, std::tuple<T *...>) {}

int main()
{
    f(A<0>{}, std::tuple<char*, int*, float*>{});
}

f 的第二个重载不是更专业吗? g++ 4.9.2 表示调用不明确,clang 3.6.0 接受它。哪个编译器是对的?

有意思的是,如果你把std::tuple&lt;T *...&gt;改成std::tuple&lt;T...&gt;,g++就可以了,我没看懂。

【问题讨论】:

  • MSVC 2013 对此也很满意:)
  • 我怀疑 gcc 是错误的,但值模板参数可能有些晦涩难懂(标准往往围绕它们古怪)。你可以在不使用值的情况下回购吗?
  • clang 代码也可以。
  • @Yakk Repro 使用类型。

标签: c++ function c++11 compiler-errors overloading


【解决方案1】:

根据当前规则,第二个重载更专业。某些具有合成值 @ 的特化 A&lt;@&gt; 不能与 A&lt;0&gt; 匹配,但 A&lt;0&gt; 可以与 A&lt;I&gt; 匹配(与 I=0)。第一对的不对称性是决定性的。无论您使用T 还是T* 作为第二个参数中的模式都无关紧要,因为该对的两种方式都成功演绎。

该错误仍然存​​在于主干中,并由@Barry 报告为67228

【讨论】:

  • 注意:CWG 1391 的决议可能会使这变得模棱两可。不过我不确定。
  • 是的,我认为分辨率不太正确。查看 bogdan 的回答 here,我认为他对如何实际解决措辞有一些好主意。
猜你喜欢
  • 1970-01-01
  • 2017-06-19
  • 2012-08-22
  • 2014-11-26
  • 1970-01-01
  • 2013-09-01
  • 1970-01-01
  • 2015-03-21
相关资源
最近更新 更多