好,实际上解决方案相对容易。在类专业化之前添加模板operator<<
的declaration
在下面的代码中,A
是模板类,取决于非类型的bool type
参数。为operator<<
和A<true>
都定义了一个朋友A<false>
。 operator<<
另外取决于另一个布尔模板参数。
#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;
}
现在,我想提供模板参数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:错误:朋友'模板std :: ostream&运算符<
27 | std :: ostream&运算符<
main.cpp:14:26:注意:'template std :: ostream&运算符<
14 |朋友std :: ostream&运算符<
在以下代码中,A是模板类,取决于非类型布尔类型参数。为A
好,实际上解决方案相对容易。在类专业化之前添加模板operator<<
的declaration
template <bool type> class A; template <bool d = false, bool type> std::ostream& operator<<(std::ostream& os, const A<type>& a); ....
以这种方式,
friend
中的A<type>
声明不会首先声明operator<<
,而只会声明它是friend
。可以检查一个有效的例子here。
好,实际上解决方案相对容易。在类专业化之前添加模板operator<<
的declaration