我试图在模板类中为模板类编写外部类模板运算符。
我希望以下代码片段能解释我的意思。
property
当我写这样的运算符时:
enum MyEnum {};
template <MyEnum a>
class ClassWithTemplateClass {
public:
template <bool B>
class TemplateClass {
// ...
};
};
编译器返回错误:
错误:声明&#39;运营商&lt;&lt;&#39;作为无功能
你能告诉我应该怎么写这个算子吗?
答案 0 :(得分:1)
ClassWithTemplateClass<enumVal>::
是nested name specifier,而non-deduced context又是DEMO。由于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;
}
};
或,(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;
}
,或(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;
}
作为另一种选择,(5)您可以将调用从operator<<
调度到另一个函数,并明确指定其模板参数,以便签名完全符合您的要求,并且模板参数是已知的:< / p>
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;
}
{{3}}