mora
mora

Reputation: 2287

lookup template function with friend keyword

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

Answers (1)

Jarod42
Jarod42

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.
};

Live Demo

Or to provide definition inside the class:

template<typename T>
class A {
    friend void friendFunction(A<T> const& val) // It is not template
    {
        /*Definition*/
    }
};

Demo

Upvotes: 1

Related Questions