mercredi 2 septembre 2015

Conditional template specialization

How can I provide a default virtual method implementation for a class template if the template parameter is constructible? If it isn't constructible (at least with the default constructor), the method should be kept abstract.

My attempt was to create a class specialization enabled only if the template parameter is constructible, as shown below:

#include <iostream>
#include <type_traits>

using namespace std;

struct ShouldNotBeAbstract {};

struct ShouldBeAbstract {
    ShouldBeAbstract(int) {
    }
};

template <typename T, typename = void>
struct Test {
    virtual void method() = 0;
};

template <typename T>
struct Test<T, enable_if<is_constructible<T>::value>::type> {
    virtual void method() {}
};

int main(int argc, char* argv[]) {
    cout << "Should not be abstract: " << is_constructible<Test<ShouldNotBeAbstract> >::value << endl;
    cout << "Should be abstract: " << is_constructible<Test<ShouldBeAbstract> >::value << endl;

    return 0;
}

However, I get the following error when compiling with g++ -std=c++11 test.cpp:

test_conditional_template_specialization.cpp:19:62: error: type/value mismatch at argument 3 in template parameter list for ‘template<class T, class P, class> struct Test’
 struct Test<T, P, enable_if<is_constructible<T>::value>::type> {
                                                              ^

test_conditional_template_specialization.cpp:19:62: error:   expected a type, got ‘std::enable_if<std::is_constructible<T>::value>::type’

Why does this error appear? And what would be a better way to achieve my goal?

Aucun commentaire:

Enregistrer un commentaire