2012-07-30 123 views
5

什么是声明一个模板类的友元函数的正确方法(为的std :: ostream的&操作< <)在.cpp文件C++:在模板类运营商友元函数<<

我当前的实现不工作:

// MyTest.h 
template<class T, unsigned int TSIZE> class MyTest 
{ 
    inline friend std::ostream& operator<< <T, TSIZE> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs); 
}; 

// MyTest.cpp 
template<class T, unsigned int TSIZE> inline friend std::ostream& operator<< <T, TSIZE> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs) 
{ 
    // IMPLEMENTATION 
} 

非常感谢您!

+0

你究竟是什么意思的“不工作”......编译器错误?哪些错误?首先猜测...“朋友”不属于.cpp版本。 – 2012-07-30 04:37:35

回答

7

要像你一样引用operator<< <T, TSIZE>这是一个模板专业化,主模板的声明必须是可见的。反过来,operator<<需要声明MyTest,因为它作为参数出现。

// Declare MyTest because operator<< needs it 
template<class T, unsigned int TSIZE> class MyTest; 

// Declare primary template 
template<class T, unsigned int TSIZE> 
inline std::ostream& operator<<(std::ostream& lhs, const MyText<T, TSIZE>& rhs); 

template<class T, unsigned int TSIZE> class MyTest 
{ 
    // Specialization MyTest<T, TSIZE> only declares 
    // specialization operator<< <T, TSIZE> as friend 
    // Note that you can just use '<>' to designate the specialization, 
    // template parameters are deduced from the argument list in this case 
    inline friend std::ostream& operator<< <> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs); 
}; 

您的定义应该与这些声明相匹配。请注意,因为operator<<是一个模板,所以它的定义应该很有可能在标题中。

当谈到编写所有这些先发制人的声明时,需要较少工作的替代方案是MyTest<T, TSIZE>将整个模板声明为朋友,而不仅仅是需要MyTest<T, TSIZE>的专业化。

// in MyTest definition 
template<typename U, unsigned USIZE> 
inline friend std::ostream& operator<<(std::ostream& lhs, const MyTest<U, USIZE>& rhs); 

你必须定义也应该符合这样的声明(模板参数的名称有匹配的声明和定义没有关系)。

为了完整起见,我会提到,当谈到类模板的朋友时,另一种方法是在类模板定义中定义它。这为每个专业化定义了一个非模板的朋友函数。

// in MyTest definition 
friend std::ostream& operator<<(std::ostream& lhs, MyTest const& rhs) 
{ /* implementation */ } 

这是不可能将此类功能(例如&ns::operator<<不起作用,不像其他选项),并且它们仅通过ADL找到。

0

这并不完全清楚原来的帖子想要什么。我会认为它希望以下内容:

// Some template class. 
template<class T, unsigned int TSIZE> class MyTest { }; 

// Some template function. 
template<class T, unsigned int TSIZE> std::ostream& operator<< (std::ostream &lhs, const MyTest<T, TSIZE> &rhs) 
{ 
    // IMPLEMENTATION 
} 

现在是需要声明这个模板函数作为类的朋友,因为这个功能需要访问的My test保护对象。这可以用下面的定义来实现:需要在friend声明的前

template<class T, unsigned int TSIZE> class MyTest 
{ 
    template<class T1, unsigned int TSIZE1> 
    friend std::ostream& operator<< (std::ostream &lhs, const MyTest<T1, TSIZE1> &rhs); 
}; 

模板头,因为这是一个不相关的模板函数,不属于当前模板类。