Неявно выбирать тип и размер элемента массива из косвенного параметра шаблона

У меня есть класс, и в зависимости от значения параметра шаблона я хотел бы изменить тип элемента и размер массива.

Приведенное ниже очевидно не компилируется, но я использую его, чтобы показать, что я хотел бы сделать.

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 как еще два параметра шаблона, но есть ли способ избежать этого?

Пожалуйста, не редактируйте сообщения, чтобы изменить синтаксис, который, по вашему мнению, является лучшим.

intrigued_66 06.04.2024 13:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
60
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Сделайте что-нибудь в этом духе:

#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>;

Chris 04.04.2024 00:48

нужно ли ключевое слово typename в последней строке?

M.M 04.04.2024 00:53

@M.M пфф... возможно, да. Это одна из вещей, которые я просто добавляю, если/когда компилятор жалуется. Вернее, я бы все равно использовал conditional_t в большинстве случаев, так как мне не нужно возиться с C++11... но я добавлю его на всякий случай. Спасибо!

Christian Stieber 04.04.2024 00:56

Списывание ответа Кристиана Штибера, но изменение, чтобы поместить все вычисления в параметры шаблона. 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;
};

На богболте.

Другие вопросы по теме