So I was answering this question: Define friend function template of class template, and I found some "weird" behavior from g++ (5.3) and clang (3.8):
Let's assume the following template:
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);
}
This compile with both compiler (as expected - If this should not compile, feel free to comment and explain why).
If I change things to:
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) { /* ... */ }
This compile with g++ but not with clang, and if I set one to auto and the other one to a specific value, e.g.:
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) { /* ... */ }
Both compiler reject the code saying that:
error: 'int test<2>::value' is private
My two related questions are:
auto for both declaration/definition)?auto when defining the function and test<K> when declaring the friendship?Or in one question: What are the rules about auto for friend function declarations when the function is defined outside the class?
Consider [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.
I.e. if the friend declaration uses auto and the second declaration does not, they don't match. The other way around is guaranteed by core issue 2081. Finally, if both use auto, the declarations should indeed match as per [temp.over.link]/6, so Clang is incorrect in that case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With