In the following code, A
is a template class, depending on a non-type bool type
parameter. A friend operator<<
is defined for both A<true>
and A<false>
. The operator<<
additionally depends on another bool template parameter.
#include <ostream>
#include <iostream>
#include <type_traits>
template <bool type>
class A;
template <>
class A<true> {
int m_x;
public:
A(int x) : m_x{x} { }
template <bool d, bool type>
friend std::ostream& operator<<(std::ostream& os, const A<type>& a);
};
template <>
class A<false> {
int m_y;
public:
A(int y) : m_y{y} { }
template <bool d, bool type>
friend std::ostream& operator<<(std::ostream& os, const A<type>& a);
};
template <bool d, bool type>
std::ostream& operator<<(std::ostream& os, const A<type>& a)
{
if constexpr (type) {
os << "m_x = " << a.m_x << std::endl;
if constexpr (d) { os << "2m_x = " << a.m_x << std::endl; }
}
else {
os << "m_y = " << a.m_y << std::endl;
if constexpr (d) { os << "2m_y = " << a.m_y << std::endl; }
}
return os;
}
int main()
{
A<true> atrue{2};
A<false> afalse{3};
operator<< <true>(std::cout, atrue);
operator<< <false>(std::cout, atrue);
operator<< <true>(std::cout, afalse);
operator<< <false>(std::cout, afalse);
return 0;
}
See it live on Coliru.
Now, I would like to give a default value of the template parameter d
of operator<<
, say d=false
such that this statement
std::cout << atrue;
is equivalent to
operator<< <false>(std::cout, atrue);
because bool d
takes a default value d=false
and bool type
is deduced from the second argument of operator<<
.
Is there a syntax to allow for that?
If I insert the default parameter in the friend declaration
template <bool d = false, bool type>
friend std::ostream& operator<<(std::ostream& os, const A<type>& a);
I get a compile error:
main.cpp:14:71: error: default template arguments may not be used in template friend declarations
If I insert the default parameter in the code of operator<<
template <bool d = false, bool type>
std::ostream& operator<<(std::ostream& os, const A<type>& a)
{
...
again it does not compile giving error
main.cpp:27:15: error: redeclaration of friend 'template std::ostream& operator<<(std::ostream&, const A&)' may not have default template arguments
27 | std::ostream& operator<<(std::ostream& os, const A& a)
main.cpp:14:26: note: 'template std::ostream& operator<<(std::ostream&, const A&)' previously declared here
14 | friend std::ostream& operator<<(std::ostream& os, const A& a);
operator <<
asprint
as you cannot use it "normally"? – Jarod42