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 <<asprintas you cannot use it "normally"?