dimanche 3 juin 2018

Using CRTP with partial class specialization?

I'm trying to mix-in an operator [] with a class. My problem is I've partially specialized the class, and the compiler doesn't like me not specifying the template parameters to the derived class:

#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];
}

With clang this gives:

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 is even less helpful:

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()’:

Is my only option to re-specify the template parameters inside of the mixin clause?

Aucun commentaire:

Enregistrer un commentaire