如何声明运算符<<对于内部课程

时间:2011-06-29 12:26:43

标签: c++ templates operator-overloading forward-declaration nested-class

//cannot declare operator<<(...) here:
//forward declarations:
class External;

template<class T, class Y>
class External::Internal;

template<class T, class Y>
std::ostream& operator<<(std::ostream& out, const External::Internal<T,Y>&);

class External
{
    template<class T, class Y>
    class Internal
    {};

    Internal data_;

    void print() {
        /*out is a std::ostream*/
        out << data_;
    }
};

template<class T, class Y>
std::ostream& operator<<(std::ostream& out, const External::Internal<T,Y>&)
{ }

我确实要为operator<<实施Internal但是当我尝试使用来自External的此操作符调用时出现问题:当此运算符为时,它不会看到此运算符在此类的定义下声明,似乎无法在此类定义之上声明此运算符。

6 个答案:

答案 0 :(得分:1)

template<class T, class Y>
std::ostream& operator<<(std::ostream& out,const External::Internal<T, Y>&)
                                                 ^^^^^^^^^^        ^^^^^^
{

}

并确保将此功能声明为friend,因为Internal中的External是私有的

更新 的 这是你如何宣布一个朋友。在你的类定义中写:

template<class T, class Y>
friend  std::ostream& operator <<(std::ostream& out, const External::Internal<T,Y>&)

由于朋友声明是声明,这将解决您的前向声明问题。

更新:解决循环依赖:

首先向前宣布internal

template<class T, class Y>
class Internal;

然后宣布这位朋友。

然后你的其他同学,它应该工作。

答案 1 :(得分:1)

Armen的答案适用于<<运营商本身。

但是,您的会员声明

Internal data_;

也是不正确的,以同样的方式。即,缺少Internal的模板参数。因此,除了修复您的运营商实施外,还要修复您的会员声明。

最后,请记住,在C ++中,除非已经声明,否则不能使用某些东西。您在<<的内联实施中对print的使用违反了该要求。所以你最好重新安排一些事情(或者只是声明它们),以便已经宣布使用过的任何内容。

干杯&amp;第h。,

答案 2 :(得分:1)

重点是使用前向声明:

// you promise there will be implementation of this stuff later on:
template<typename T, typename Y>
class External::Internal<T, Y>;

template<typename T, typename Y>
std::ostream& operator<<(std::ostream& out, const External::Internal<T, Y>&);

// now declare your class and operator<< function as normal
class External
{
    template<class T, class Y>
    class Internal
    {
    };

    Internal<Foo, Bar> data_;

    void print()
    {
        // here you can use operator<< with Internal
        out << data_;
    }
};

template<class T, class Y>
std::ostream& operator<<(std::ostream& out,const External::Internal<T, Y>&)
{
}

答案 3 :(得分:1)

如果您问如何将Internal<>::operator<<定义为朋友,那么:

class External
{
  template<class T, class Y>
  class Internal
  {
    friend std::ostream& operator <<(std::ostream& out, const Internal&)
    {
      // impl
      return out;
    }
  };

  Internal<Foo, Bar> data_;

public:
  void print() const
  {
    /*out is a std::ostream*/
    out << data_;
  }
};

答案 4 :(得分:0)

template<class T, class Y>
std::ostream& operator<<(std::ostream& out, const External::Internal<T, Y>&)
{
}

External::表现为命名空间,是必需的,因为operator<<定义不属于外部类。

答案 5 :(得分:0)

  

当我尝试使用来自外部

的此操作员调用时出现问题

不要在类定义中编写过程代码。只有声明。

按顺序写:

  • 班级定义[标题中]
  • operator<< [标题中]
  • 使用这些内容的代码[在源文件中]