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]
精彩评论