在模板外部重载模板类的输出流操作符

Overload output stream operator of a template class outside of the template

本文关键字:输出流 操作符 重载 外部      更新时间:2023-10-16

我想在模板类定义之外重载输出流操作符<<

在模板类中实现它是可以的:

template
<typename T,int _MaxSize=10,template <class C> class Policy=NoCheck,typename Container=std::vector<T>>
class MyContainer : public Policy<T>
{
public:
  MyContainer():p(_MaxSize){};
  std::ostream& operator<<(MyContainer<T,_MaxSize,Policy,Container>& obj){ };
private:
  Container p;
};

但是当我尝试在模板类之外执行时:

template
<typename T,int _MaxSize=10,template <class C> class Policy=NoCheck,typename Container=std::vector<T>>
class MyContainer : public Policy<T>
{
public:
  MyContainer():p(_MaxSize){};
  friend std::ostream& operator<<(std::ostream& out,MyContainer<T,_MaxSize,Policy,Container> obj);
private:
  Container p;
};
template
<typename T,int _MaxSize,template <class C> class Policy,typename Container>
std::ostream& operator<<(std::ostream& out,MyContainer<T,_MaxSize,Policy,Container> obj)
{
};

编译器抱怨:

warning: friend declaration ‘std::ostream& operator<<(std::ostream&, MyContainer<T, _MaxSize, Policy, Container>)’ declares a non-template function [-Wnon-template-friend]
tempstruct.cc:39:97: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)

有没有人能给出一个简单的例子,说明如何在模板类之外定义输出流操作符<< ?

在相关的帖子中,我发现这里每个人都在模板类中做

谁能给一个简单的例子,如何输出流操作符<<在模板类之外定义?

不,因为它不简单。我可以举一个复杂的例子:

// Declare the class template, because we need it to declare the operator
template <typename,int,template <class C> class,typename> class MyContainer;
// Declare the operator, because (as the error says) templates must be declared
// in the namespace before you can declare them friends. At this point, we can't
// define the operator, since the class template is incomplete.
template 
<typename T,int _MaxSize,template <class C> class Policy,typename Container>
std::ostream& operator<<(std::ostream&,MyContainer<T,_MaxSize,Policy,Container>);
// Define the class template
template
<typename T,int _MaxSize=10,template <class C> class Policy=NoCheck,typename Container=std::vector<T>>
class MyContainer : public Policy<T>
{
public:
  MyContainer():p(_MaxSize){};
  // Include <> to indicate that this is the template
  friend std::ostream& operator<< <>(std::ostream& out,MyContainer<T,_MaxSize,Policy,Container> obj);
private:
  Container p;
};
// Finally define the operator
template
<typename T,int _MaxSize,template <class C> class Policy,typename Container>
std::ostream& operator<<(std::ostream& out,MyContainer<T,_MaxSize,Policy,Container> obj)
{
  // print some stuff
};

在相关的帖子中,我发现这里每个人都在模板类中这样做。

我会那样做;这样就简单多了。或者,更好的是,我将根据公共接口实现输出,假设它提供对容器内容的充分访问。那么就不需要友元声明了,因此也就不需要forward声明了。