Tak było odpowiedzi na to pytanie: Define friend function template of class template i znalazłem jakieś „dziwne” zachowanie z g ++ (5.3) i szczęk (3.8):Powrót typ mecz z auto i znajomych funkcji
załóżmy następujący szablon :
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);
}
to skompilować zarówno kompilatora (zgodnie z oczekiwaniami - Jeśli to nie powinno skompilować, prosimy o komentarz i wyjaśnienie dlaczego).
Jeśli zmienię rzeczy:
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) { /* ... */ }
to skompilować z g ++, ale nie z hukiem, a jeśli ustawić jeden do auto
a drugi do określonej wartości, np
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) { /* ... */ }
Oba kompilatory odrzucają kod, który mówi:
error: 'int test<2>::value' is private
Moje dwa powiązane pytania to:
- Który kompilator jest odpowiedni dla pierwszego przypadku (
auto
dla deklaracji/definicji)? - Dlaczego nie można użyć
auto
podczas definiowania funkcji itest<K>
podczas deklarowania przyjaźni?
lub w jednym pytaniu: Jakie są zasady przyjmowania zgłoszeń o auto
funkcyjnych przyjaciel gdy funkcja jest zdefiniowana poza klasą?