2012-03-08 60 views
1

我有一個類Vector<T>,我正在使用提供類YAML::Node的類。我想爲這兩種類型重載operator>>操作符>>過載的明確實例化

我加入了以下聲明Vector的聲明:

friend void operator>>(YAML::Node const & node, Vector<T> & v); 

我還增加了以下實現功能:

template<typename T> 
void operator>>(YAML::Node const & node, Vector<T> & v) { 
    node[0] >> v.x; 
    node[1] >> v.y; 
    node[2] >> v.z; 
} 

最後,我添加了以下(未遂at)明確實例化模板T = num_t

template 
void operator>>(YAML::Node const & node, Vector<num_t> & v); 

然而,這會導致下面的鏈接錯誤:

Error 9 error LNK2019: unresolved external symbol "void __cdecl operator>>(class YAML::Node const &,class Vector<double> &)" ([email protected]@[email protected]@[email protected]@@@Z) referenced in function "public: static class Scene __cdecl Scene::fromFile(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" ([email protected]@@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@Z) 

num_tdouble一個typedef)

但是,如果我添加以下(非模板)實現的功能,一切編譯罰款:

void operator>>(YAML::Node const & node, Vector<num_t> & v) { 
    node[0] >> v.x; 
    node[1] >> v.y; 
    node[2] >> v.z; 
} 

爲什麼模板版本的功能不能正常工作?

編輯:忘記提及;編譯器是Visual Studio 11 Beta

回答

3

聲明函數爲friend確實不是聲明函數模板;相反,類模板的每個特化都會聲明一個非模板函數,其參數類型根據模板參數進行重載。將選擇這些而不是您定義的模板;但他們沒有定義,因此錯誤。

要修復它,您可以在類模板之前聲明函數模板(在這種情況下,朋友聲明將使該朋友聲明爲朋友,而不是聲明新函數),或者在類中定義內聯函數模板,以便類模板的每個專業化定義函數並聲明它。

+0

謝謝,現在有道理! – 2012-03-08 01:27:54

0

這很奇怪。我看不到任何錯誤,甚至MSDN文檔(這是Visual C++的權利?)確認模板實例化應該推導出模板參數。實例化中的參數匹配。也許這是超載運營商破產?

嘗試在其上添加顯式模板參數並沒有什麼壞處。

此外,也許它是由typedef混淆?你永遠不會知道!嘗試替換double。

2

嗯,問題是您聲明的friend是一個非模板函數,它與您的移位運算符完全無關。事實上,您的模板使用編譯器應該抱怨的任何私有成員。這裏有一個例子這應該什麼樣子:

template <typename T> 
class foo 
{ 
public: 
    template <typename S> 
    friend void f(foo<S>); 

private: 
    T value; 
}; 

template <typename T> 
void f(foo<T> v) 
{ 
    v.value; 
} 
template void f(foo<int>); 

int main() 
{ 
    foo<int> v; 
    f(v); 
} 

如果通過

friend void f(foo<T>); 

更換friend聲明此代碼將無法鏈接或者與實際上會產生表明函數編譯時錯誤f()不是朋友。