I have a template class (with SFINAE condition) and I'd like to overload a template operator <<
for it.
This code works, but it also allow all operator <<
overloaded for all types T
to access Foo
as friends.
How can I get only operator <<
of type Foo
to be friend
of Foo
class?
I tried forward declaration of Foo
class and operator
but can make it work because of the use of enable_if
Does anyone have an idea of how to do this?
template< typename T, enable_if_t< condition_v<T>, int> = 0 >
class Foo
{
// ...
template< typename Ar, typename R> friend Ar& operator<<(Ar& os, const Foo<R>& foo);
};
template< typename Ar, typename T>
inline Ar& operator<<(Ar& ar, const Foo<T>& foo)
{
// ...
return ar;
}
The easiest way to resolve friend
and template
issues is to define the friend
within the class(1), usually:
template< typename T, std::enable_if_t< condition_v<T>, int> = 0 >
class Foo
{
template< typename Ar > friend Ar& operator<<(Ar& os, const Foo& foo) {
// ...
return os;
}
};
Note that this defines a function template where Foo
is not a template parameter.
Only Ar
is a template parameter.
This is typically desirable because it simplifies overload resolution, which can fix some ambiguous cases, and it may improve compilation speed.
(1) Colloquially, such a friend
is called "hidden friend".