将变量的名称传递给 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;
或者,Qt 的 QObject
s 可以有这种名为 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...);
}
我正在尝试创建打印功能。我希望它能够接收变量列表并打印出 它们的值和它们的名称 。到目前为止,我有以下代码:
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;
或者,Qt 的 QObject
s 可以有这种名为 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...);
}