Как использовать std:: enable_if с вариационным шаблоном

Я пытаюсь создать класс Tensor (для тех, кто не знает, что это математический эквивалент многомерного массива), и я хочу только разрешить его компиляцию, если он был создан с типом, который удовлетворяет определенному типу -traits.

Обычно я бы сделал что-то вроде:

template <typename t,="" std::size_t="" size,="" typename="" enable="void">
class Foo;
// Only allow instantiation of trivial types:
template <typename t,="" std::size_t="" size="">
class Foo<t, size,="" typename="" std::enable_if<std::is_trivial<t="">::value>::type>
{
 // Implement stuff...
};
</t,></typename></typename>

Тем не менее, мне требуется неизвестное число параметров шаблона, чтобы указать границы каждого измерения моего тензорного объекта, например:

template <typename t,="" std::size_t...="" sizes,="" typename="" enable="void">
class CTensor;
template <typename t,="" std::size_t="" sizes="">
class CTensor<t, sizes...,="" typename="" std::enable_if<std::is_trivial<t="">::value>::type>
{
 // Implement stuff...
};
</t,></typename></typename>

Однако это не работает из-за параметра вариационного шаблона Sizes.... Я хочу создать экземпляр объекта CTensor следующим образом:

CTensor<int, 5="" 3,="" 4,=""> testTensor; // Compiles fine and produces a rank 3 tensor
CTensor<complexclass, 5="" 3,="" 4,=""> testTensor2; // Produces a compile-time error
</complexclass,></int,>

Каков наилучший способ достижения этого?

2 ответа

Почему вы используете enable_if для класса? Он предназначен для того, чтобы функции не отображались во время поиска перегрузки. Если все, что вы хотите сделать, это утверждать, что определенные условия всегда соблюдаются, используйте static_assert.

template <typename t,="" std::size_t...sizes="">
class CTensor
{
 static_assert(std::is_trivial<t>::value, "T required to be a trivial type");
};
</t></typename>


Как насчет использования enable_if? Это не то, для чего он предназначен для использования (SFINAE). Похоже, что все, что вы хотите сделать, это static assert:

template <typename t,="" std::size_t...="" sizes="">
class CTensor
{
 static_assert(std::is_trivial<t>::value, "expecting trivial type blah blah");
};
</t></typename>

licensed under cc by-sa 3.0 with attribution.