带有typedef的可变参数CRTP

时间:2018-07-12 22:06:21

标签: c++ templates crtp variadic

我正在使用可变的CRTP来尝试一些代码来创建mixin。我希望可以根据用户选择的类型对mixins进行模板化。我基本上已经尝试过了:

template <class Base>
class Feature1 {
public:
    // why doesn't this work?!
    // using value_type = typename Base::value_type;
public:
    void extraMethod1() {
        auto base = static_cast<Base&>(*this);
        base.basicMethod();
    }
};

template <class T, template <typename> class ... Skills>
class X : public Skills<X<T, Skills...>>... {
public:
    using value_type = T;
public:
    void basicMethod() {
    }
};

using X1 = X<int, Feature1>;

所以我的问题是Base::basicMethod是否可访问,为什么我会遇到Base::value_type的错误?

错误是:

X.cpp:6:37: error: no type named 'value_type' in 'X<int, Feature1>'
                using value_type = typename Base::value_type;
                                   ~~~~~~~~~~~~~~~^~~~~~~~~~
X.cpp:15:19: note: in instantiation of template class 'Feature1<X<int, Feature1> >' requested here
        class X : public Skills<X<T, Skills...>>... {

clang和g ++都给出类似的错误,c ++的版本为14或17(因为这只是一个实验)。

1 个答案:

答案 0 :(得分:1)

使用CRTP时,Base类中的Feature1类仍然不完整。

因此您不能使用其中定义的别名。

作为解决方法,您可以创建特征。

template <typename T>
struct MyTrait;

template <class Base>
class Feature1 {
public:
    using value_type = typename MyTrait<Base>::type;
public:
    void extraMethod1() {
        auto base = static_cast<Base&>(*this);
        base.basicMethod();
    }
};


template <class T, template <typename> class ... Skills>
class X;

template <class T, template <typename> class ... Skills>
struct MyTrait<X<T, Skills>>
{
    using type = T;
};

template <class T, template <typename> class ... Skills>
class X : public Skills<X<T, Skills...>>... {
public:
    using value_type = typename MyTrait<X>::type;
public:
    void basicMethod() {}
};