Reputation: 17120
//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.
Upvotes: 0
Views: 2275
Reputation: 62975
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_;
}
};
Upvotes: 1
Reputation: 385164
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:
operator<<
[in header]Upvotes: 0
Reputation: 133004
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.
Upvotes: 1
Reputation: 1941
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>&)
{
}
Upvotes: 1
Reputation: 145279
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.,
Upvotes: 1
Reputation: 1
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.
Upvotes: 0