c++ - 模板类的友元运算符<<,带有附加的默认模板参数
问题描述
在下面的代码中,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:错误:重新声明朋友'模板 std::ostream& operator<<(std::ostream&, const A&)' 可能没有默认模板参数
27 | std::ostream& 运算符<<(std::ostream& os, const A& a)
main.cpp:14:26: 注意:'template std::ostream& operator<<(std::ostream&, const A&)' 之前在这里声明
14 | 朋友 std::ostream& 运算符<<(std::ostream& os, const A& a);
解决方案
好的,实际上解决方案相对容易。在类特化之前添加模板声明就足够了operator<<
:
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
. 可以在此处检查一个工作示例。
推荐阅读
- android - AltBeacon 库作为前台服务,活动元素在激活时出现问题
- javascript - 为什么来自字符串的 Javascript 日期与来自 Date 对象的相同日期不同
- angular - Angular RxJS 地图
有 api 请求 - angular - 错误:StaticInjectorError(AppModule)[NgIf -> ViewContainerRef]:将角度 6 升级到 7 后
- blockchain - 当块数较少时使用区块链会有用吗?
- unity3d - 统一。构建不播放动画
- postgresql - Postgres 迁移 9.2.1 到 9.2.4
- c# - ASP.NET Core 从 2.1 迁移 -> 2.2 Azure 部署中的依赖项问题
- c# - 在 C# 中调用 Delphi COM 对象会引发 AccessViolationException
- database - 将数据从 rdbms 数据库视图发布并显示到网页,动态地,仅更改数据库视图并在浏览器上按 F5