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

Pass the name of a variable to a function in C++

本文关键字:C++ 函数 变量      更新时间:2023-10-16

我正在尝试创建一个打印函数。我希望它能够接收变量列表并打印出它们的值和名称。到目前为止,我有以下代码:

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++做到这一点?如果是这样,如何?

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

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

在这里现场观看:http://ideone.com/UopOni

或者,Qt的QObject可以有这种称为属性的命名变量

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

有没有办法在C++做到这一点?如果是这样,如何?

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


使用纯 c++ 语言是不可能的,但 c 预处理器可用于创建变量名称的字符串化(请参阅 # 运算符)版本,并将其用于调试/日志记录输出。

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

有没有办法在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?我认为没有。

使用 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...);
}

演示