Reputation: 2287
everyone
I am a beginner of c++. Now I try to understand how compiler lookup a function with friend keyword. The followings are the code with warning and error messages. I have two problems in the code. One is warning and another is error.
At Problem(1), compiler warns that function including template parameter is non-template function. Why is it non-template function? And how can I define a function including template parameter as non-template function?
At Problem(2), friend template function, friendFunction(A const& val), is not looked up. In my understanding, it can be looked up by ADL method.
Please tell me how to understand the two problem above. Thank you very much.
template<typename T>
class A {
/* ***** first declaration of functions without definition.
* ***** In this case, compiler assume the friend function will be defined
* ***** in one outer namespace, in this case ::. */
friend void friendFunction(A<T> const& val); // Problem(1) warning: please see below for message
// warning: friend declaration ‘void friendFunction(const A<T>&)’ declares a non-template function
};
// ??? How can I define friend void friendFunction(A<T> const& val) ???
template<typename T>
void friendFunction(A<T> const& val) {
std::cout << "::function(A<T>)" << std::endl;
}
void call_FriendFunction(A<int>* ptr);
void test_friend_keyword() {
A<int> a;
call_FriendFunction(&a);
}
void call_FriendFunction(A<int>* ptr) {
friendFunction(*ptr); // Problem(2) please see error message below
// undefined reference to `friendFunction(A<int> const&)'
/* In my understanding, the following friendFunction(*ptr); can be looked up
* by the following logic.
* (1) friendFunction(ptr) here is unqualified name.
* (2) Because friendFunction(*ptr) has an augment of A<int>* ptr,
* friendFunction(*ptr) have related class and related namespace of class A.
* (3) class A has declaration of
* friend void friendFunction(A<T> const& val);
* And it is allowed to see the friend template function.
* (4) As a result, friendFunction(*ptr) is looked up as
* friend void ::friendFunction(A<T> const& val); */
}
Upvotes: 0
Views: 56
Reputation: 217135
For the warning with
friend void friendFunction(A<T> const& val);
Assume that T
in int
, it declares
friend void friendFunction(A<int> const& val);
So you have to define
void friendFunction(A<int> const& val);
which is not the same as
template<typename T>
void friendFunction(A<int> const& val);
or even
template<>
void friendFunction<int>(A<int> const& val);
The possible fixes are to declare a template function friendFunction
before:
template<typename T> class A;
template <typename T> void friendFunction(A<T> const& val);
template<typename T>
class A {
friend void friendFunction<>(A<T> const& val); // It is the template function
// Only the one with T is friend.
};
Or to provide definition inside the class:
template<typename T>
class A {
friend void friendFunction(A<T> const& val) // It is not template
{
/*Definition*/
}
};
Upvotes: 1