2015-10-04 63 views
0

全部查找模板功能与朋友关键字

我是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

对于

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

警告假设Tint,它声明

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

+0

谢谢Jarod42,这是一个美丽的答案。 – mora