所以我回答了这个问题: 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 K>
friend auto foo(test<U> const t);
template <int M, int N = 2 * M>
test<N> foo (test<M> const t) { /* ... */ }
两个编译器都拒绝代码说:
错误:&#39; int test&lt; 2&gt; :: value&#39;是私人的
我的两个相关问题是:
auto
)?auto
,在宣布友谊时使用test<K>
?或者在一个问题中:当在课堂外定义函数时,有关友元函数声明的auto
的规则是什么?
答案 0 :(得分:4)
功能或功能模板的重新声明或特化 使用占位符类型的声明返回类型也应该 使用该占位符,而不是推断类型。
即。如果朋友声明使用auto
而第二声明不使用,则他们不匹配。另一种方法是由core issue 2081保证。最后,如果两者都使用auto
,则声明应该按照[temp.over.link]/6匹配,因此在这种情况下Clang不正确。