开发者

How to declare operator<< for internal 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>&)
{ }

I do want to implement operator<< for Internal but there is a problem when I try to use this operator call from External: It doesn't see this operator when this operator is declared under the definition of this class, and there seems to be no way of declaring this operator above this class definition.


If you're asking how to define Internal<>::operator<< as a friend, then:

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


Armen's answer would work for the << operator itself.

However, your member declaration

Internal data_;

is also incorrect, in the same way. I.e., lacking template arguments for Internal. So in addition to fixing your operator implementation, fix also your member declaration.

Finally, remember that in C++ you can't use something unless it has already been declared. Your usage of << in the inline implementation of print violates that. So you'd better rearrange things (or just declare them) so that anything that's used, is already declared.

Cheers & hth.,


The point is in using forward declarations:

// 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>&)
{
}


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

}

And make sure to declare this function a friend, because Internal is private in External

Update: here's how you declare a friend. In your class definition write:

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

Since a friend-declaration is a declaration, this will solve your forward-declaration issue.

Update: To solve the circular dependency:

First forward-declare internal

template<class T, class Y>
class Internal;

then declare the friend.

Then the rest of your class, it should work.


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

The External:: behaves as a namespace and is required because operator<< definition is outside of class External.


there is a problem when I try to use this operator call from External

Don't write procedural code inside your class definition. Only declarations.

Write, in order:

  • Class definition [in header]
  • operator<< [in header]
  • Code that uses these things [in source file]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜