Шаблон псевдонима с переключением параметров шаблона

Рассмотрим объявление шаблона псевдонима, зависящее от одного параметра шаблона, который может иметь конечное число значений, например class enum. Я хотел бы использовать использование для определения псевдонима типа для каждого значения class enum.

Один из способов реализации — использовать std::conditional:

class enum color { white, red, blue };

struct A {};
struct B {};
struct C {};

template <color c>
using data = std::conditional_t<c == color::white, A, std::conditional_t<c == color::red, B, C>>;

Очевидно, что когда class enum color расширяется до новых значений, нужна дополнительная вложенная std::conditional, что довольно громоздко. Я ищу решение, чтобы выразить это «масштабируемым» способом, то есть таким, чтобы при расширении class enum нужно было выполнять минимальную работу. Что-то вроде

template <class c>
using data = some_struct<c, A, B, C>;

где some_struct "выбрать" тип A, B, C в зависимости от первого параметра c.

Как я могу реализовать это (масштабируемым способом)?

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

dfrib 12.01.2023 14:53

вы всегда выбираете между A, B и C, а если вы добавляете значение, то добавляете D? Или это любой 3 тип? Я не уверен, что вы хотите получить some_struct, или это просто ваша попытка получить data?

463035818_is_not_a_number 12.01.2023 14:56

@dfrib правильно, я изменил заголовок и текст

francesco 12.01.2023 14:56

@ 463035818_is_not_a_number Я намерен добавить новый элемент цвета x и соответствующий struct D, чтобы data<x> = D.

francesco 12.01.2023 14:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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
4
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Один из способов сделать это — создать кортеж типов для выбора и сопоставить их с порядком перечисления, которое у вас есть. Затем вы можете просто получить тип из кортежа по индексу значения перечисления. Это будет выглядеть как

using type_set = std::tuple<A, B, C>;

template <color c>
using data_t = typename std::tuple_element<static_cast<size_t>(c), type_set>::type;

Теперь все, что вам нужно сделать, это добавить типы в кортеж, который определяет type_set, когда вы добавляете перечисления в color. Вы можете увидеть, как это работает в этом живом примере, который использует сообщение об ошибке, чтобы сообщить вам, что data_t<color::red> разрешается в тип B.

Вы можете использовать специализацию. Основные и вспомогательные:

template <color c> struct data;
template <color c> using data_t = data<T>::type; 

Тогда для каждого случая записывается одна его специализация:

template <> struct data<color::white> { using type = A; }
template <> struct data<color::red> { using type = B; }
// ...

Добавление нового перечисления, сопоставленного с новым типом, означает просто добавление специализации.

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

Как я могу заменить ключевое слово автоматической ссылки в этом коде?
Разрешение перегрузки для шаблонов функций с автоматическим параметром шаблона, отличным от типа
Руководство по выводу шаблона не работает с лямбда, но не с глобальной функцией
Как добавить специализацию шаблона для универсального метода в универсальном классе, когда два типа равны?
Как вывести аргумент шаблона при сохранении класса с лямбда-шаблоном в качестве члена другого класса?
C++: функция шаблона, принимающая функцию, которая принимает другую функцию, которая использует ссылку на тип шаблона в качестве параметра
Использование рекурсивных параметров шаблона с переменным числом аргументов в возвращаемом типе функции
Нет функции сопоставления для лямбда со ссылочным аргументом
Шаблон C++ для проверки, реализует ли тип ввода `оператор []`
С++ 20 концепций альтернативы в С#