2015-05-29 67 views
0

我試圖在普通類上實現朋友模板函數。對朋友模板函數的未定義引用

fren.h

#include <iostream> 

namespace sn{ 


class Fren{ 
    private: 
    int x; 

    public: 
    Fren(int y):x(y){ 

    } 

template<typename B> 
friend void getValue(B& asd); 

}; 



template<typename B> 
void getValue(B& asd); 

} 

fren.cpp

#include "fren.h" 

namespace sn{ 

template<typename B> 
void getValue(B& asd){ 
    std::cout<<asd.x<<std::endl; 
} 
} 

的main.cpp

#include "fren.h" 

int main() { 

sn::Fren f(10); 
sn::getValue(f); 
return 0; 
} 

我試圖讓弗倫的私有值x。

但我得到「未定義的引用」錯誤。

+2

閱讀此:[「爲什麼模板只能在頭文件中實現?」](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the- ?頭文件S = 2 | 2.7508)。 – WhozCraig

+0

我能夠通過明確的瞬時實現多個文件的模板類,但這是一個類。我想知道功能是否可行。 –

+0

如果您現在詢問模板函數是否顯式實例化,[是,它們是](http://en.cppreference.com/w/cpp/language/function_template)。 – WhozCraig

回答

2

首先,除非有其他原因,否則大部分屬於單個頭文件。請參閱"Why can templates only be implemented in the header file?"爲什麼。

也就是說,如果你想爲你的函數模板使用顯式實例,你可以。請注意以下幾點,它比你的朋友更受限制。此代碼只有朋友與匹配模板參數的函數模板Fren

func.h

#ifndef SAMPLE_FUNC_H 
#define SAMPLE_FUNC_H 

namespace sn 
{ 

template<class T> 
struct Fren; 

template<class T> 
void getValue(const Fren<T>& s); 

template<class T> 
struct Fren 
{ 
    friend void getValue <>(const Fren<T>&); 

    Fren() : x(42) {} 

private: 
    int x; 
}; 

} // namespace 


#endif 

func.cpp

#include "func.h" 
#include <iostream> 

namespace sn 
{ 

template<class T> 
void getValue(const Fren<T>& s) 
{ 
    std::cout << s.x << ':' << __PRETTY_FUNCTION__ << '\n'; 
} 

// explicit instantiation here 
template void getValue <int> (const Fren<int>&); 

} 

的main.cpp

#include <iostream> 
#include <string> 
#include "func.h" 

int main() 
{ 
    sn::Fren<int> s; 
    sn::getValue(s); 
} 

輸出

42:void sn::func(const S<T> &) [T = int] 

與蘋果LLVM版本6.1.0(鐺 - 602.0.53)(基於LLVM 3.6.0svn)

總之編譯,你的代碼似乎是缺少實際的顯式實例化。