2015-10-04 64 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