模板类内部模板类的外部类运算符
outside class operator for template class inside template class
我正在尝试为模板类内部的模板类编写类外模板运算符。
我希望下面的片段能解释我的意思。
enum MyEnum {};
template <MyEnum a>
class ClassWithTemplateClass {
public:
template <bool B>
class TemplateClass {
// ...
};
};
当我写这样的操作员:
template <MyEnum enumVal, bool B>
auto operator<<(ClassWithTemplateClass<enumVal>::TemplateClass<B> &a, int b) {
// ...
return a;
}
编译器返回错误:
错误:'operator<lt;'作为非功能
你能告诉我该怎么写这个运算符吗?
ClassWithTemplateClass<enumVal>::
是一个嵌套的名称说明符,而它又是一个非推导上下文。由于enumVal
是出现在作用域解析运算符::
左侧的模板参数,因此编译器无法推导其值。
<<
运算符可以定义为(1)类TemplateClass
:内的朋友
enum MyEnum { X, Y, Z };
template <MyEnum E>
struct ClassWithTemplateClass
{
template <bool B>
struct TemplateClass
{
friend auto& operator<<(TemplateClass& a, int b)
{
return a;
}
};
};
其中TemplateClass
总是指ClassWithTemplateClass<?>::TemplateClass<?>
的特定实例化
演示
或(2)ClassWithTemplateClass
:内部
enum MyEnum { X, Y, Z };
template <MyEnum E>
struct ClassWithTemplateClass
{
template <bool B>
struct TemplateClass
{
};
template <bool B>
friend auto& operator<<(TemplateClass<B>& a, int b)
{
return a;
}
};
演示2
或者,(3)您可以为每个预定义的枚举值提供一个单独的运算符定义(尽管它可以有比定义为常量更多的值),因此只需要推导B
:
enum MyEnum { X, Y, Z };
template <MyEnum E>
struct ClassWithTemplateClass
{
template <bool B>
struct TemplateClass
{
};
};
template <bool B>
auto& operator<<(ClassWithTemplateClass<X>::TemplateClass<B>& a, int b)
{
return a;
}
template <bool B>
auto& operator<<(ClassWithTemplateClass<Y>::TemplateClass<B>& a, int b)
{
return a;
}
template <bool B>
auto& operator<<(ClassWithTemplateClass<Z>::TemplateClass<B>& a, int b)
{
return a;
}
演示3
,或(4)将模板参数存储为TemplateClass
的静态数据成员,并使用它们使运算符SFINAE能够检索它们的值:
enum MyEnum { X, Y, Z };
template <MyEnum E>
struct ClassWithTemplateClass
{
template <bool B>
struct TemplateClass
{
static constexpr MyEnum ClassWithTemplateClass_E = E;
static constexpr bool TemplateClass_B = B;
};
};
template <typename T
, MyEnum E = T::ClassWithTemplateClass_E
, bool B = T::TemplateClass_B>
auto& operator<<(T& a, int b)
{
return a;
}
演示4
作为另一种选择,(5)您可以将调用从operator<<
调度到另一个函数,并显式指定其模板参数,这样签名就完全符合您的要求,并且模板参数是已知的:
enum MyEnum { X, Y, Z };
template <MyEnum E>
struct ClassWithTemplateClass;
template <MyEnum E, bool B>
auto& print(typename ClassWithTemplateClass<E>::template TemplateClass<B>& a, int b);
template <MyEnum E>
struct ClassWithTemplateClass
{
template <bool B>
struct TemplateClass
{
friend auto& operator<<(TemplateClass& a, int b)
{
return print<E, B>(a, b);
}
};
};
template <MyEnum E, bool B>
auto& print(typename ClassWithTemplateClass<E>::template TemplateClass<B>& a, int b)
{
return a;
}
演示5
相关文章:
- 为什么比较运算符如此快速
- 在类设计中查找外部命名空间中的重载运算符
- 运算符过载上未解决的外部符号
- 结构外部的重载运算符
- 在类外部定义显式运算符 bool() 时出错
- 内部和外部过载C++运算符之间的差异
- 模板结构外部的重载运算符
- 错误:LINK2019:在命名空间中使用运算符<<时未解析的外部符号
- C++运算符重载输入运算符>>,将类外部的对象作为成员
- 使用数组外部地址的数组运算符
- 外部C结构的C++默认复制/移动赋值运算符不是常量
- Windows 上的 GMP 库 - 链接错误 LNK2001 未解析的外部符号运算符<<
- 尝试重载=运算符时出现1个未解析的外部错误
- 将比较运算符"运算符<"实现为成员函数或外部函数
- 为什么我的输出运算符 <<() 函数定义会导致无法解析的外部符号错误?
- 模板上的算术运算符过载,导致无法解析的外部错误
- 在具有隐式转换的模板类外部重载运算符
- 何时使用内部运算符,何时使用外部运算符
- 是否可以在结构外部编写自动转换运算符
- 如何从 C++ 中的外部函数调用删除运算符