2016-03-18 3 views
0

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

std::ostream& debug_values(std::ostream& out); 

template <typename V, typename... R> 
std::ostream& debug_values(
    std::ostream& out, const V& value, const R&... remaining) { 
    out << value << ", "; 
    debug_values(out, remaining...); 
    return out; 
} 

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

ostream out; 
int i1 = 1; 
int i2 = 2; 
debug_values(out, i1, i2) //Will print 1, 2 

Вместо этого, я хотел бы debug_values ​​напечатать следующее:

debug_values(out, i1, i2); //i1: 1, i2: 2 

Есть ли способ сделать это в C++? Если да, то как?

+1

Существует всегда '' # макро путь ... – CompuChip

+1

Использование макросов, вероятно, единственный способ сделать это. –

ответ

2

Вы не можете использовать чистый C++ для достижения этого. Однако вы можете использовать препроцессор для достижения того, что вы хотите

#define PP(expr) std::cout<<#expr<<" "<<expr<<std::endl; 

Посмотреть здесь жить: http://ideone.com/UopOni

В качестве альтернативы, в Qt QObject s может иметь этот вид именованных переменных под названием properties

Это решение является полезно для отладки или ведения журнала, но это не очень красиво.

0

Есть ли способ сделать это на C++? Если да, то как?

Вы можете использовать std::map.

ostream out; 
int i1 = 1; 
int i2 = 2; 
std::map<std::string, int> values; 
values["i1"] = i1; 
values["i2"] = i2; 

// Change debug_values to use the map as its second argument type 
debug_values(out, values) 

Есть ли способ автоматизировать создание map? Я не думаю, что есть.

2

Есть ли способ сделать это на C++? Если да, то как?

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


Это не представляется возможным использовать обычный C++ язык, но с-препроцессор может быть использован для создания stringized (см # оператор) версий имен переменных, и использовать их для отладки/каротажного вывода.

Недостаток заключается в том, что вам необходимо создать версии возможного макроса debug_values(), которые разрешены на фиксированное количество заданных аргументов (хотя у IIRC есть доступные библиотеки макро метапрограммирования, которые помогают реализовать такой материал проще).

0

С MACRO, вы можете сделать

// (up to hard coded 6 arguments) 
#define NARGS_(_1, _2, _3, _4, _5 , _6, N, ...) N 
#define NARGS(...) NARGS_(__VA_ARGS__, 6, 5, 4, 3, 2, 1) 

#define CAT_(a, b) a ## b 
#define CAT(a, b) CAT_(a, b) 

#define name_1(x)      #x, x 
#define name_2(x, x2)     #x, x, #x2, x2 
#define name_3(x, x2, x3)    #x, x, #x2, x2, #x3, x3 
#define name_4(x, x2, x3, x4)   #x, x, #x2, x2, #x3, x3, #x4, x4 
#define name_5(x, x2, x3, x4, x5)  #x, x, #x2, x2, #x3, x3, #x4, x4, #x5, x5 
#define name_6(x, x2, x3, x4, x5, x6) #x, x, #x2, x2, #x3, x3, #x4, x4, #x5, x5, #x6, x6 

#define names(...) CAT(name_, NARGS(__VA_ARGS__))(__VA_ARGS__) 
#define debug_values(out, ...) debug_values_impl(out, names(__VA_ARGS__)) 

std::ostream& debug_values_impl(std::ostream& out) { return out << std::endl; } 
template <typename T, typename ... Ts> 
std::ostream& 
debug_values_impl(std::ostream& out, const char* name, const T& value, const Ts&... args) 
{ 
    out << name << ':' << value << ", "; 
    return debug_values_impl(out, args...); 
} 

Demo