В следующем коде A
является классом шаблона, в зависимости от нетипичного параметра bool type
. Друг operator<<
определен для A<true>
и A<false>
. operator<<
дополнительно зависит от другого параметра шаблона bool.
#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;
}
См. в прямом эфире на Coliru .
Теперь я хотел бы указать значение по умолчанию: параметр шаблона d
из operator<<
, скажем d=false
такой, что этот оператор
std::cout << atrue;
эквивалентен
operator<< <false>(std::cout, atrue);
, поскольку bool d
принимает значение по умолчанию d=false
и bool type
выводится из второго аргумента operator<<
.
Существует ли синтаксис, позволяющий это сделать?
Если я вставлю параметр по умолчанию в объявление друга
template <bool d = false, bool type>
friend std::ostream& operator<<(std::ostream& os, const A<type>& a);
Я получаю ошибку компиляции:
main. cpp: 14: 71: ошибка: аргументы шаблона по умолчанию не могут использоваться в объявлениях друзей шаблона
Если я вставлю параметр по умолчанию в код operator<<
template <bool d = false, bool type>
std::ostream& operator<<(std::ostream& os, const A<type>& a)
{
...
снова, он не скомпилируется, выдав ошибку
main. cpp: 27: 15 : ошибка: переопределение друга 'template std :: ostream & operator << (std :: ostream &, const A &)' может не иметь аргументов шаблона по умолчанию * 1 047 * <p>27 | std :: ostream & operator << (std :: ostream & os, const A & a) </p>
main. cpp: 14: 26: примечание: 'шаблон std :: ostream & operator << (std :: ostream & , const A &) 'ранее заявлено здесь </p>
14 | друг std :: ostream & operator << (std :: ostream & os, const A & a); </p>