2015-08-15 77 views
14
#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说这个调用是模糊的,铿锵3.6.0接受它。哪个编译器是正确的?`不是`void f(A <0>,tuple <T *...>)`比'void f(A <I>,tuple <T *...>)`更专业化吗?

有意思的是,如果你将std::tuple<T *...>更改为std::tuple<T...>,那么g ++就没问题了,我不明白。

+0

MSVC 2013也对此感到满意:) –

+0

我怀疑gcc是错误的,但可能有些值模板参数不明确(标准往往会在它们周围变得古怪)。你可以不用价值回购? – Yakk

+0

[clang](http://clang.llvm.org)也可以用代码。 –

回答

5

按照现行规则,第二次过载更专业。一些专业A<@>与合成值@不能匹配A<0>,但A<0>可以匹配A<I>(与I=0)。这第一对的不对称是决定性的。无论您使用的是T还是T*作为第二个参数中的模式都是无关紧要的,因为扣除对这对货币的双向成功。

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

+0

注:CWG 1391号决议可能会使此含糊不清。但我不确定。 – Columbo

+0

是的,我认为决议并不完全正确。看看bogdan的答案[这里](http://stackoverflow.com/a/31735126/2069064),我认为他对如何真正解决措辞有一些很好的想法。 – Barry

+3

我已提交[67228](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67228)。 – Barry

相关问题