所以我回答了这个问题:
Define friend function template of class template,我从g(5.3)和clang(3.8)中发现了一些“怪异”的行为:
我们假设以下模板:
template<int M> struct test { private: int value; template<int U,int K> friend test<K> foo (test<U> const t); }; template <int M,int N = 2 * M> test<N> foo (test<M> const t) { test<N> r; r.value = t.value; return r; } int main(){ test<1> t; foo(t); }
这与两个编译器一起编译(如预期的那样 – 如果这不应该编译,请随意发表评论并解释原因).
如果我改变了:
template<int U,int K> friend auto foo(test<U> const t); template <int M,int N = 2 * M> auto foo (test<M> const t) { /* ... */ }
这用g编译但不用clang编译,如果我将一个设置为auto而另一个设置为特定值,例如:
template<int U,int K> friend test<K> foo(test<U> const t); template <int M,int N = 2 * M> auto foo (test<M> const t) { /* ... */ } // or: template<int U,int N = 2 * M> test<N> foo (test<M> const t) { /* ... */ }
两个编译器拒绝代码说:
error: ‘int test<2>::value’ is private
我的两个相关问题是:
解决方法
考虑
[dcl.spec.auto]/13:
Redeclarations or specializations of a function or function template
with a declared return type that uses a placeholder type shall also
use that placeholder,not a deduced type.
即如果朋友声明使用auto而第二声明不使用,则它们不匹配.另一种方法是由core issue 2081保证.最后,如果两者都使用auto,声明应该确实匹配[temp.over.link]/6,所以在这种情况下Clang是不正确的.