【问题标题】:Explicit specialization of friend function for a class template类模板的友元函数的显式特化
【发布时间】:2012-11-19 23:11:37
【问题描述】:

我正在阅读 litb 对问题 here 的回答,其中详细介绍了如何创建类模板的专用友元函数

我试图创建一个符合他建议的示例(代码在末尾​​em>):

// use '<>' to specialize the function template with the class template's type
friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f)

这会导致编译器错误

error: defining explicit specialization ‘operator<< <>’ in friend declaration

在特化中显式声明模板参数也不起作用:

friend std::ostream& operator<< <T>(std::ostream& os, const foo<T>& f) // same error

另一方面,从使用特化改为使用朋友函数模板而不是确实工作:

template<typename U>
friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works

所以我的问题是:

  • 是什么导致了第一个错误?
  • 如何将ostream operator 显式特化为周围的类模板特化?

示例代码如下:

#include <iostream>

// fwd declarations
template<typename T> struct foo;
template<typename T> std::ostream& operator<<(std::ostream&, const foo<T>&);

template<typename T>
struct foo
{
    foo(T val)
        : _val(val)
    {}

    friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f) // error line
    //template<typename U>
    //friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
    {
        return os << "val=" << f._val;
    }

    T _val;
};


int main()
{
    foo<std::string> f("hello world");
    std::cout << f << std::endl;
    exit(0);
}

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    在 litb 的示例中,他只是将专业化声明为班级中的朋友。他没有定义专业化,这就是您的代码正在做的事情。不允许在类声明(或任何非命名空间范围)中定义特化。

    你需要的是这样的:

    template <class T>
    class foo;
    
    template<class T>
    std::ostream& operator<<(std::ostream& os, const foo<T>& f)
    {
        return os << "val=" << f._val;
    }
    
    template<typename T> 
    struct foo
    {
        // ...
    private:
        friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f);
        T _val;
    };
    

    【讨论】:

      【解决方案2】:

      你有两个选择:

      删除 fwd 声明并定义类中的所有内容。

      示例

      template <typename U>
      friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
      {
          return os << "val=" << f._val;
      }
      

      在类之外定义友元函数。

      示例

      template<typename T> struct foo;
      template<typename T> std::ostream& operator<<(std::ostream&, const foo<T>&);
      
      template<typename T>
      struct foo
      {
          foo(T val)
              : _val(val)
          {}
      
          friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f);
      
          T _val;
      };
      
      template <typename T>
      std::ostream& operator<<(std::ostream& os, const foo<T>& f)
      {
             return os << "val=" << f._val;
      }
      

      【讨论】:

      • 在类之外定义友元函数将不允许我专门研究用于实例化原始类模板的类型。
      • 删除 fwd 声明没有任何区别——我仍然不能使用类模板的类型作为友元函数模板的特化。 (现在错误是declaration of ‘operator&lt;&lt;’ as non-function
      • 感谢 Jesse - 通过您的编辑,我现在看到了您的建议。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-19
      • 1970-01-01
      • 2011-07-15
      • 2011-07-27
      相关资源
      最近更新 更多