У меня есть класс, и в зависимости от значения параметра шаблона я хотел бы изменить тип элемента и размер массива.
Приведенное ниже очевидно не компилируется, но я использую его, чтобы показать, что я хотел бы сделать.
struct A {};
struct B {};
template <size_t N>
class C
{
// This is illegal syntax, just using it as pseudo-code
if constexpr(N <= 5)
{
std::array<A, 20> _array;
}
else
{
std::array<B, 80> _array;
}
};
(N не размер массива)
Я знаю, что мог бы передать A и 20 как еще два параметра шаблона, но есть ли способ избежать этого?





Сделайте что-нибудь в этом духе:
#include <type_traits>
template<size_t N> class C {
typedef std::array<A,20> First;
typedef std::array<B,80> Second;
typename std::conditional<N<=5, First, Second>::type _array;
// C++14 and later lets you to do this:
// std::conditional_t<N<=5, First, Second> _array;
};
Или возможно using First = std::array<A,20>; using Second = std::array<B,80>;
нужно ли ключевое слово typename в последней строке?
@M.M пфф... возможно, да. Это одна из вещей, которые я просто добавляю, если/когда компилятор жалуется. Вернее, я бы все равно использовал conditional_t в большинстве случаев, так как мне не нужно возиться с C++11... но я добавлю его на всякий случай. Спасибо!
Списывание ответа Кристиана Штибера, но изменение, чтобы поместить все вычисления в параметры шаблона. N — единственный параметр шаблона, который необходимо указать, но могут быть и другие, которые могут сделать это более гибким.
#include <type_traits>
#include <array>
struct A {};
struct B {};
template<
std::size_t N,
typename F = std::array<A, 20>,
typename S = std::array<B, 80>,
typename T = typename std::conditional<N <= 5, F, S>::type
>
class C {
T _array;
};
На богболте.
Пожалуйста, не редактируйте сообщения, чтобы изменить синтаксис, который, по вашему мнению, является лучшим.