使用好友关键字

时间:2015-10-04 12:24:33

标签: c++ templates friend

大家

我是c ++的初学者。现在我尝试理解编译器如何使用friend关键字查找函数。 以下是带有警告和错误消息的代码。 我在代码中有两个问题。一个是警告,另一个是错误。

在问题(1)中,编译器警告包含模板参数的函数是非模板函数。为什么它是非模板功能?如何定义一个包含模板参数的函数作为非模板函数?

在问题(2)中,不查找朋友模板函数friendFunction(A const& val)。根据我的理解,它可以通过ADL方法查找。

请告诉我如何理解上面的两个问题。 非常感谢你。

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); */
}

1 个答案:

答案 0 :(得分:1)

用于

的警告
friend void friendFunction(A<T> const& val);

假设T中的int,它声明了

friend void friendFunction(A<int> const& val);

所以你必须定义

void friendFunction(A<int> const& val);

不一样
template<typename T>
void friendFunction(A<int> const& val);

甚至

template<>
void friendFunction<int>(A<int> const& val);

可能的修复方法是在:

之前声明模板函数friendFunction
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

或者在课堂内提供定义:

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

Demo