将变量的名称传递给 C++ 中的函数

Pass the name of a variable to a function in 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++ 中做到这一点?如果是,怎么做?

Is there a way to do this in C++? If so, how?

您可以使用 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?我觉得没有。

Is there a way to do this in C++? If so, how?

不,你不能这样做,当你将变量作为参数传递时,变量名不会以某种方式保留。


使用普通的 c++ 语言是不可能的,但 c 预处理器可用于创建变量名的字符串化(请参阅 # 运算符)版本,并将它们用于 debug/logging 输出.

缺点是,您必须创建可能的 debug_values() 宏的版本,这些版本解析为固定数量的给定参数(尽管 IIRC 有可用的宏元编程库,支持实现此类东西更容易)。

您不能使用纯 C++ 来实现它。 但是你可以使用预处理器来实现你想要的

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

现场观看:http://ideone.com/UopOni

或者,Qt 的 QObjects 可以有这种名为 properties

的命名变量

此解决方案对于调试或日志记录很有用,但不是很漂亮。

使用 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