c – 模板类中模板类的外部类操作符
发布时间:2020-12-16 07:14:55 所属栏目:百科 来源:网络整理
导读:我正在尝试在模板类中为模板类编写外部类模板运算符. 我希望以下片段能解释我的意思. enum MyEnum {};template MyEnum aclass ClassWithTemplateClass { public: template bool B class TemplateClass { // ... };}; 当我写这样的运算符: template MyEnum e
我正在尝试在模板类中为模板类编写外部类模板运算符.
我希望以下片段能解释我的意思. 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<<'的声明作为非功能 你能告诉我怎么写这个运算符吗? 解决方法
ClassWithTemplateClass< enumVal> ::是
nested name specifier,而
nested name specifier又是
non-deduced context.由于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<?> DEMO 或者(2)在ClassWithTemplateClass中: enum MyEnum { X,Z }; template <MyEnum E> struct ClassWithTemplateClass { template <bool B> struct TemplateClass { }; template <bool B> friend auto& operator<<(TemplateClass<B>& a,int b) { return a; } }; DEMO 2 或者,(3)您可以为每个预定义的枚举值提供单独的运算符定义(尽管它可以具有比定义为常量更多的值),因此只需要推导出B: enum MyEnum { X,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; } DEMO 3 ,或(4)将模板参数存储为TemplateClass的静态数据成员,并使用它们使操作符SFINAE能够并检索它们的值: enum MyEnum { X,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; } DEMO 4 作为另一种选择,(5)你可以从操作符<<<<到另一个函数,并显式指定其模板参数,以便签名完全符合您的要求,并且模板参数是已知的: enum MyEnum { X,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,int b) { return a; } DEMO 5 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |