使用CRTP与部分类专业化?

时间:2018-06-03 20:53:21

标签: c++ c++11 templates template-meta-programming

我正在尝试将operator []与一个类混合在一起。我的问题是我已经部分专门化了这个类,编译器不喜欢我没有为派生类指定模板参数:

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T>
struct mixin {
    template <typename U>
    void operator[](U u) {
        cout << u;
    }
};


template <typename T, typename = void>
struct derived : mixin<derived> {};


template <typename T>
struct derived<T, 
    typename enable_if<
        is_same<T, int>{}
    >::type> : mixin<derived> {};


int main() {
    derived<int> d;
    d[3.14];
}

对于clang,这给出了:

test.cc:16:24: error: use of class template 'derived' requires template arguments
struct derived : mixin<derived> {};
                       ^~~~~~~
test.cc:16:8: note: template is declared here
struct derived : mixin<derived> {};
       ^
test.cc:23:22: error: use of class template 'derived' requires template arguments
    >::type> : mixin<derived> {};
                     ^~~~~~~
test.cc:16:8: note: template is declared here
struct derived : mixin<derived> {};
       ^

gcc的帮助更少:

test.cc:16:31: error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> struct mixin’
 struct derived : mixin<derived> {};
                               ^
test.cc:16:31: note:   expected a type, got ‘derived’
test.cc:23:29: error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> struct mixin’
     >::type> : mixin<derived> {};
                             ^
test.cc:23:29: note:   expected a type, got ‘derived’
test.cc: In function ‘int main()’:

我唯一的选择是在mixin子句中重新指定模板参数吗?

1 个答案:

答案 0 :(得分:2)

好吧,试试这个:

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T>
struct mixin {
    template <typename U>
    void operator[](U u) {
        cout << u;
    }
};


template <typename T, typename = void>
struct derived : mixin<derived<T>> {};


template <typename T>
struct derived<T,
    typename enable_if<
        is_same<T, int>::value
    >::type> : mixin<derived<T>> {};


int main() {
    derived<int> d;
    d[3.14];
}

work ...

我改变了什么:

  1. 使用is_same<foo,bar>::value,而不是is_same<foo,bar>{} 编辑嗯,看来你根本不需要改变它。整洁!
  2. 在使用mixin<derived>时,不试图让编译器推导出派生的模板参数。你在那里方式过于乐观......