samedi 28 mars 2020

Why `void` is required while declaring a class template which is to be specialized using `enable_if`

I'm learning C++ template meta-programming and stumbled upon a simple SFINAE related (I believe so) issue. In particular, I'm writing a template class which will give us the type with largest size. I'm aliasing the type to be the right type depending upon their size by comparing types with sizeof operator. I'm selecting correct class specialization using enable_if. What I don't understand is why void needs to be provided as default value for class Enable while declaring a class template which is to be specialized using enable_if.

Following code works just fine

// test.cpp
#include <type_traits>

// void works just fine but if changed to anything else say int, compilation fails!
template < typename L, typename R, class Enable = void > struct MaxTypeT;

template < typename L, typename R >
struct MaxTypeT<L, R, typename std::enable_if< (sizeof(L) >= sizeof(R)) >::type> {
    using type = L;
};

template < typename L, typename R >
struct MaxTypeT<L, R, typename std::enable_if< (sizeof(L) < sizeof(R)) >::type> {
    using type = R;
};

int main(){
    static_assert(std::is_same< MaxTypeT<int, double>::type, double >::value, "MaxTypeT not working");
    return 0;
}

but when I change class Enable = void to any other type say class Enable = int, then I get following error. Why void is necessary here?

test.cpp: In function ‘int main()’:
test.cpp:17:56: error: incomplete type ‘MaxTypeT<int, double>’ used in nested name specifier
     static_assert(std::is_same< MaxTypeT<int, double>::type, double >::value, "MaxTypeT not working");
                                                        ^~~~
test.cpp:17:56: error: incomplete type ‘MaxTypeT<int, double>’ used in nested name specifier
test.cpp:17:69: error: template argument 1 is invalid
     static_assert(std::is_same< MaxTypeT<int, double>::type, double >::value, "MaxTypeT not working");

Aucun commentaire:

Enregistrer un commentaire