Компиляция карты времени имени строки типа в типы в C++

В C++ можно создать карту времени компиляции строковых имен типов в типы. Я знаю, что сами типы не могут быть сопоставлены, но можем ли мы, например, сопоставить метафункции шаблона, которые предоставляют тип?

В частности, мы могли бы, например, иметь одну метафункцию шаблона варада, которая принимает некоторый начальный набор типов, а затем во время компиляции создает статическую карту, используя, например, выражение свертки, чтобы во время выполнения мы могли получить доступ к открытому типу и использовать его в качестве параметра шаблона. в другую функцию, что-то вроде этого

TypeMapper::Map["Type1"]::type

Итак, во время выполнения, если бы мы хотели, например, выполнить определенную шаблонную функцию, мы могли бы сделать

MyTypeProcessor<TypeMapper::Map["Type1"]::type>();

Если это невозможно из-за ограничений языка, мне интересно, какое конкретно ограничение, потому что по отдельности я считаю, что отдельные части идеи в некоторой степени осуществимы, но я просто не уверен, как это сделать, поэтому, если я что-то здесь упускаю помощь будет очень признательна. Я все еще новичок в этом, поэтому могу некоторые вещи неправильно понимать.

Для чего тебе это нужно? Прежде всего, вы уверены, что хотите, чтобы это происходило во время компиляции? Это означало бы, что у каждого TU будет своя собственная карта, а не одна глобальная карта.

HolyBlackCat 22.06.2024 08:30

Вы же не пытаетесь создать какой-то код отражения или сериализации? Потому что сериализация, как известно, сложна в реализации, а отражение (во время выполнения) на самом деле не соответствует философии проектирования C++. C++ — это язык, который очень ориентирован на фазу компиляции. Итак, вместо описания того, КАК вы хотите что-то делать, можете ли вы также объяснить, ЧЕГО вы пытаетесь достичь?

Pepijn Kramer 22.06.2024 08:37

Этот синтаксис не может работать. Map должно быть выражением (а не типом), как и Map["Type1"], поэтому Map["Type1"]::type не может быть допустимым. Но мы можем это упростить! Поскольку это выражение предположительно отображается в Type1 во время компиляции, мы можем просто заменить его на Type1.

n. m. could be an AI 22.06.2024 09:16

Типы никогда не могут определяться значениями времени выполнения. Скорее всего, вы делаете это неправильно.

Passer By 22.06.2024 09:20
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Это возможно с другим синтаксисом.

Нам бы хотелось, чтобы строковые литералы можно было использовать в качестве нетиповых параметров шаблона, но в настоящее время C++ этого не позволяет. Итак, давайте создадим замену, которая будет столь же хороша функционально, но менее удобна.

  template <std::size_t N>
  struct ct_string
  {
      char value[N] = {};
      consteval ct_string(const char (&str)[N]) : value{}
      {
          for (std::size_t i = 0; i < N; ++i) value[i] = str[i];
      }
  };
  
  
  template <std::size_t N>
  consteval auto make_ct_string(const char (&str)[N])
  {
      return ct_string<N>(str);
  }

Теперь make_ct_string("foo") возвращает значение, которое можно использовать как NTTP. Мы можем использовать его для пометки типов строками.

  template <typename K>
  struct is_ct_string_t : public std::false_type {};
  template <std::size_t N>
  struct is_ct_string_t<ct_string<N>> : public std::true_type {};
  
  template <typename K>
  concept is_ct_string = is_ct_string_t<K>::value;
  
  template <auto cst> requires is_ct_string<decltype(cst)>
  struct tagged_with_string
  {
      static constexpr auto value = cst;
      consteval static std::string_view tag() { return cst.value; }
  };

Отсюда мы можем использовать такие типы, как tagged_with_string<make_ct_string("foo")>.

  using tagged_abc = tagged_with_string<make_ct_string("abc")>;
  constexpr auto abc_tag = tagged_abc::tag();

Вы можете построить карту следующим образом:

  template <auto cst> requires is_ct_string<decltype(cst)> struct Map {}
  template <auto cst> requires is_ct_string<decltype(cst)> struct Map {};
  template <> struct Map <make_ct_string("int")> { using type = int; };
  template <> struct Map <make_ct_string("double")> { using type = double; };

  using foo = Map<make_ct_string("double")>::type;
  static_assert(std::is_same_v<foo, double>);

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

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

Вычисление чисел, для которых требуется тип данных размером более 16 байт в C++
Введите 'строка | логическое значение не может быть назначено для ввода «никогда» в машинописном тексте
Почему тип int меняет размер в зависимости от архитектуры процессора, а другие типы — нет?
Определение макроса и использование типов данных для поиска абсолютного значения
Аргумент func с массивом смешанных типов (протокол), затем вызовите статический метод протокола
Не удалось преобразовать число с плавающей запятой 64 в число с плавающей запятой 32 в Python
Как перегрузить процедуру, объявленную в абстрактном типе в Фортране?
Разъяснение: «Значение значения определяется типом выражения, используемого для доступа к нему»
Как изменить неопределенный тип как необязательный в машинописном тексте?
Что вызывает синтаксическую ошибку в агрегате расширения Ada для ограниченного типа? Закомментированный сектин получает синтаксическую ошибку