模板类中模板类的外部类操作符

时间:2015-12-20 13:34:23

标签: c++ c++11 c++14

我试图在模板类中为模板类编写外部类模板运算符。

我希望以下代码片段能解释我的意思。

property

当我写这样的运算符时:

enum MyEnum {};

template <MyEnum a>
class ClassWithTemplateClass {
 public:
    template <bool B> 
    class TemplateClass {
        // ...
    };
};

编译器返回错误:

错误:声明&#39;运营商&lt;&lt;&#39;作为无功能

你能告诉我应该怎么写这个算子吗?

1 个答案:

答案 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<?>

的特定实例

DEMO 2

或(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;
    }
};

DEMO 3

或,(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;
}

DEMO 4

,或(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;
}

DEMO 5

作为另一种选择,(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}}