【问题标题】:C++ : friend function in a template class for operator<<C++:运算符<<的模板类中的友元函数
【发布时间】:2012-07-30 04:33:29
【问题描述】:

在 .cpp 文件中声明模板类的友元函数(对于 std::ostream& 运算符在 .cpp 文件中的正确方法是什么?

我当前的实现不起作用:

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

非常感谢!

【问题讨论】:

  • “不起作用”到底是什么意思...编译器错误?哪些错误?首先猜测......“朋友”不属于.cpp版本。

标签: c++ templates friend ostream


【解决方案1】:

要像你一样引用operator&lt;&lt; &lt;T, TSIZE&gt;,这是一个模板特化,主模板的声明必须是可见的。而operator&lt;&lt; 需要声明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&lt;&lt; 是一个模板,它的定义很可能应该在标题中。

在编写所有这些抢先声明时需要较少工作的另一种方法是 MyTest&lt;T, TSIZE&gt; 将整个模板声明为友元,而不仅仅是采用 MyTest&lt;T, TSIZE&gt; 的特化。

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

无法引用此类函数(例如,&amp;ns::operator&lt;&lt; 不起作用,与其他选项不同)并且只能通过 ADL 找到。

【讨论】:

    【解决方案2】:

    尚不完全清楚原始帖子想要什么。我会假设它想要以下内容:

    // 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 的受保护对象。这可以通过以下定义来实现:

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

    friend 声明前面需要模板头,因为这是一个不相关的模板函数,不属于当前模板类。

    【讨论】:

      猜你喜欢
      • 2016-04-14
      • 2023-03-11
      • 1970-01-01
      • 2011-04-28
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 2016-11-28
      相关资源
      最近更新 更多