Как динамически расширить переменную в CPP

#include <iostream>
using namespace std;

const string getFileNameAsVarName(string filename, int lineNo)
{
  string s = "";
  for (char c : filename)
  {
    if (c > 'a' && c < 'z')
    {
      s += c;
    }
  }
  return s + to_string(lineNo);
}
#define DYNAMIC_NAME() (getFileNameAsVarName(__FILE__, __LINE__))
#define NAME() aaa

int main()
{
  int NAME() = 123; // OK Expands to: aaa
  int DYNAMIC_NAME() = 234; //Not OK Expands to: 
  // (getFileNameAsVarName("/Users/guichizhao/Documents/GitHub/learn/main.cpp", 29))
  return 0;
}

Это может выглядеть зашитым, но у нас есть действительный вариант использования. Наше намерение состоит в том, чтобы объявить переменную с динамическим именем, т. е. имя переменной определяется именем файла и строкой. Нет. Мы пытаемся добиться этого с помощью макроса, похоже, это единственный шанс, который мы получаем для достижения нашей цели. Проблема в том, что имя файла не является допустимым именем переменной cpp. Если мы сделаем его допустимым с помощью кода cpp, MACRO жалуется, после замены MACRO оно больше не действительно, см. комментарий в коде.

Итак, есть ли способ решить эту дилемму или есть другой способ получить переменную с динамическим именем?

Кроме того, мы используем CMake в нашем проекте, не уверен, что CMAKE может помочь, любые решения, связанные с CMAKE, также высоко ценятся.

Можем ли мы увидеть вариант использования? Как бы вы могли вернуться к переменной?

NathanOliver 03.09.2024 17:16
declare a dynamically named variableНевозможно. Если вы хотите динамически определять имена переменных, рассмотрите Python или Bash, язык сценариев. Обычно вы объединяете статическое имя с номером строки, например XCONCAT(aaa, __LINE__).
KamilCuk 03.09.2024 17:17

В целом, это похоже на вопрос XY. Какой смысл определять такую ​​переменную, если у вас никогда не будет возможности сослаться на нее? Какую реальную проблему вы пытаетесь решить?

KamilCuk 03.09.2024 17:22

Re: if (c > 'a' && c < 'z') -- это не гарантированно сработает. Используйте std::islower или, чтобы включить как строчные, так и прописные буквы, std::isalpha.

Pete Becker 03.09.2024 17:23

@NathanOliver Я задал вопрос от имени моего коллеги, я перезвоню тебе позже. Кажется, такой трюк используется проектом с открытым исходным кодом. Он следует за ним. Любой другой способ достижения той же цели определенно приветствуется.

Guichi 03.09.2024 17:25

@PeteBecker Хотя это не имеет значения... просто демо. Вопрос в том, как правильно использовать макрос.

Guichi 03.09.2024 17:26

Если вы хотите динамически добавлять имя, связанное с переменной, вам может понадобиться std::map<std::string,sometype> или std::hash_map<std::string,sometype>, где строка является именем.

drescherjm 03.09.2024 17:26

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

Guichi 03.09.2024 17:28

@drescherjm Я тоже в это верю. Я укажу вам репозиторий с открытым исходным кодом после того, как завтра доберусь до своего коллеги.

Guichi 03.09.2024 17:29

При компиляции используйте -DFILE_TOKEN=main_cpp, а затем FILE_TOKEN, чтобы имя файла было объединено с номером строки.

Eljay 03.09.2024 17:47

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

Drew Dormann 03.09.2024 18:21

Почему вы хотите это сделать? («Наше намерение состоит в том, чтобы объявить переменную с динамическим именем» — это недопустимый вариант использования, это предлагаемое вами решение для любого фактического варианта использования.) Почему имя переменной имеет значение? В любом случае имя не существует во время выполнения.

molbdnilo 03.09.2024 18:22
Стоит ли изучать 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
12
112
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вы не можете, в принципе.

Макросы обрабатываются препроцессором C++. Это работает на токенах. Он может превратить токен в строку (FOO => «FOO»), но не может превратить строку обратно в токен. Как вы обнаружили, __FILE__ — это строка, а имя переменной должно быть токеном без кавычек.

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

При компиляции используйте -DFILE_TOKEN=main_cpp, а затем FILE_TOKEN, чтобы имя файла было объединено с номером строки.


Элджей (ссылка)

И указанное выше имя файла может быть сгенерировано автоматически командной оболочкой. Большая часть этого обсуждается здесь: stackoverflow.com/questions/8487986/file-macro-shows-full-pa‌​th

Maciej Polański 03.09.2024 18:10

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