Преобразование имени переменной в строку в С++

Я хотел бы вывести некоторые данные в файл. Например, предположим, что у меня есть два вектора удвоений:

vector<double> data1(10);
vector<double> data2(10); 

существует простой способ вывода этого файла в файл, чтобы первая строка содержала заголовки 'data1' и 'data2', за которыми следует фактическое содержимое. Функция, которая выходы данных будут переданы различными различными массивами, поэтому жестко кодировать имя заголовка невозможно - в идеале я хотел бы преобразовать имя переменной к некоторой строке, а затем выводить эту строку, за которой следует содержимое векторного массива. Однако я не уверен, как преобразовать имя переменной 'data1' в строку, или действительно, если это можно легко сделать (от чтения форумов моя догадка не может) Если это невозможно, альтернативой может быть использование ассоциативного контейнер, такой как карта или, возможно, более просто контейнер "пара".

pair<vector<double>,string> data1(10,'data1');  

Любые предложения приветствуются!

Ответ 1

Вы можете использовать препроцессор "stringify" #, чтобы сделать то, что вы хотите:

#include <stdio.h>

#define PRINTER(name) printer(#name, (name))

void printer(char *name, int value) {
    printf("name: %s\tvalue: %d\n", name, value);
}

int main (int argc, char* argv[]) {
    int foo = 0;
    int bar = 1;

    PRINTER(foo);
    PRINTER(bar);

    return 0;
}


name: foo   value: 0
name: bar   value: 1

(Извините за printf, я никогда не получал разметку <iostream>. Но этого должно быть достаточно.)

Ответ 2

попробуйте следующее:

#define GET_VARIABLE_NAME(Variable) (#Variable)

//в функциях

int var=0;    
char* var_name= GET_VARIABLE_NAME(var);

Ответ 3

Вы можете использовать препроцессор, там помечен токен, но он доступен только от источника, а не от функции (вы получите имя аргумента).

Ответ 4

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

Ответ 5

Немного адаптирован из ответа @sarnold для С++:

#define DEBUG(x) std::cout << #x << " = " << x << std::endl;

Пример программы, которая использует это:

int main() {
    int foo = 1;
    DEBUG(foo);

    return 0;
}

Ответ 6

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

#define MACRO_VARIABLE_TO_STRING(Variable) (void(Variable),#Variable)

#define MACRO_FUNCTION_TO_STRING(Function) (void(&Function),#Function)

#define MACRO_METHOD_TO_STRING(ClassName,Method) (void(&ClassName::Method),#Method)

#define MACRO_TYPE_TO_STRING(Type) (void(sizeof(Type)),#Type)

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

int GetAndPrintValue(const char* VariableName)
{
   std::cout << VariableName << std::endl;
   return 10;
}

int Variable=GetAndPrintValue(MACRO_VARIABLE_TO_STRING(Variable));

Я использую такой код, когда пишу синтаксические анализаторы, которые читают данные из входного потока, и если анализируемая переменная выходит за границы, она генерирует исключение с именем переменной, которая не прошла проверку действительности.

Ответ 7

Ничего себе, это немного хитрость, одна вещь, которую вы могли бы попытаться сделать, это сделать классы или структуры, у которых есть элемент, который является строкой 'name'.