Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Friending template function from multiple classes

I have this code:

template<typename T> T f() {
// ...
}

class A {
    friend A f();
};

class B {
    friend B f();
};

I get ambiguating new declaration of ‘B f()’ error.

However, if I change my code to following

template<typename T> void f(T arg) {
// ...
}

class A {
    friend void f(A);
};

class B {
    friend void f(B);
};

program compiles finely.

Could someone help me figure out what is the problem?

like image 806
Savenkov Alexey Avatar asked Dec 12 '22 01:12

Savenkov Alexey


1 Answers

friend A f();

This line declares that the non-template function A f() exists and is a friend of the class. This is not the same function as f<A>() -- it's a completely new function.

friend B f();

This line declares another non-template function with the same name, but a different return type. You can't overload on the return type of a function, so this is forbidden.

Neither of these friend declarations refer to your template function, and in your second example the two friend declarations still don't refer to the previously-declared template function; they refer to some other non-template function, just like the friend declarations in your first example.

This is probably what you meant:

class A {
    friend A f<A>();
};

class B {
    friend B f<B>();
};

And, to fix your second example:

class A {
    friend void f<A>(A);
};

class B {
    friend void f<B>(B);
};
like image 200
cdhowie Avatar answered Dec 19 '22 04:12

cdhowie