简体   繁体   English

C ++:用于operator <的模板类中的friend函数

[英]C++ : friend function in a template class for operator<<

What is the correct way to declare a friend function of a template class (for the std::ostream& operator<<) in a .cpp file ? 在.cpp文件中声明模板类的朋友函数(对于std :: ostream和operator <<)的正确方法是什么?

My current implementation does not work : 我当前的实现不起作用:

// 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
}

Thank you very much ! 非常感谢你 !

To refer to operator<< <T, TSIZE> like you do, which is a template specialization, a declaration of the primary template must be visible. 要像您一样引用operator<< <T, TSIZE> ,这是一个模板特化,主模板的声明必须是可见的。 In turn operator<< needs a declaration of MyTest because it appears as a parameter. 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);
};

The definition you have should match those declarations. 您拥有的定义应与这些声明匹配。 Note that since operator<< is a template its definition should in all likeliness be in the header. 请注意,由于operator<<是一个模板,因此其定义应尽可能在标题中。

An alternative that requires less work when it comes to writing all those preemptive declarations is for MyTest<T, TSIZE> to declare the whole template as a friend, not just the specialization that takes MyTest<T, TSIZE> . 在编写所有这些抢先声明时,需要较少工作的替代方法是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);

The definition you have should also match such a declaration (the name of the template parameters has no bearing on matching declarations and definition). 您拥有的定义也应该匹配这样的声明(模板参数的名称与匹配的声明和定义无关)。

For the sake of completeness, I will mention that when it comes to the friend of a class template an alternative is to define it in the class template definition. 为了完整起见,我将提到,当涉及到类模板的朋友时,另一种方法是在类模板定义中定义它。 This defines a non-template friend function that is unique for each specialization. 这定义了非模板友元函数,该函数对于每个特化都是唯一的。

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

It is impossible to refer to such functions (eg &ns::operator<< doesn't work, unlike the other options) and they are only found via ADL. 不可能引用这些函数(例如&ns::operator<<不起作用,与其他选项不同),它们只能通过ADL找到。

It is not fully clear what the original post wanted. 目前还不完全清楚原帖想要什么。 I will assume that it wanted the following: 我会假设它想要以下内容:

// 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
}

Now it is necessary to declare this template function as friend of the class because this function needs access to protected objects of My test . 现在有必要将此模板函数声明为类的朋友,因为此函数需要访问My test受保护对象。 This can be achieved with the following definition: 这可以通过以下定义来实现:

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);
};

Template header is needed in front of the friend declaration because this is an unrelated template function, that does not belong to the current template class. friend声明前面需要模板头,因为这是一个不相关的模板函数,它不属于当前模板类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM