Я изучаю метапрограммирование на C ++ и наткнулся на простую проблему, связанную с SFINAE (я так считаю). В частности, я пишу шаблонный класс, который даст нам тип с наибольшим размером. Я называю type
правильным типом в зависимости от их размера, сравнивая типы с оператором sizeof
. Я выбираю правильную специализацию класса, используя enable_if
. Я не понимаю, почему void
необходимо указывать в качестве значения по умолчанию для class Enable
при объявлении шаблона класса, который должен быть специализирован, с использованием enable_if
.
Следующий код прекрасно работает
// 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;
}
но когда я заменяю class Enable = void
на любой другой тип, скажем class Enable = int
, я получаю следующую ошибку. Почему void
здесь необходим?
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");