我尝试通过向量中的名称访问类的变量。 这是我的代码:
#include <iostream>
#include <vector>
#define DECLARE(X, i) #X->i
class dut{
public:
int clock;
double reset;
dut(int a, int b){
this->clock = a;
this->reset = b;
}
~dut();
};
int main(int argc, char **argv){
dut *d = new dut(4, 5);
std::vector<std::string>var;
var.push_back("clock");
var.push_back("reset");
std::vector<std::string>::iterator it;
for(it = var.begin(); it != var.end(); ++it){
std::cout << DECLARE(d, *it) << std::endl;
}
return 0;
}
我希望在输出中看到 4 和 5。但我每次编译时遇到的错误是:
error: expected unqualified-id before ‘*’ token
25 | std::cout << DECLARE(d, *it) << std::endl;
有人可以帮我吗?
我尝试通过存储在向量中的名称来访问类的变量。
但问题是如何将字符串变量传递给宏。
如果你喜欢打印
struct
的所有字段,有一个不错的 boost::pfr 库 可以做到这一点:
#include <boost/pfr.hpp>
#include <iostream>
class dut {
public:
int clock;
double reset;
};
int main(int, char**)
{
dut d { 4, 5.433 };
boost::pfr::for_each_field(
d, [](const auto& field) { std::cout << field << '\n'; });
return 0;
}
https://godbolt.org/z/nEx683aG1
这个库有一些限制,比如没有字段名称。
哦,我想我知道你想要做的,打印
d->clock
和 d->reset
值,对吗?
那么我建议你重载
<<
运算符来打印 dut
对象。
喜欢
std::ostream operator<<(std::ostream& os, dut const& d)
{
return os << d.clock << '\n' << d.reset;
}
像输出其他任何东西一样使用它:
std::cout << *d << '\n';
另一方面,不需要对
dut
对象 d
使用指针和动态分配。
在当前的 C++ 中,您想要实现的目标并不容易。也许几年后我们将在 C++ 中实现 reflection - 那么这将很容易实现。
您根本无法轻松获取仅具有运行时名称的对象成员字段。
但是,仍然有一些选择,但很可能需要对您的项目进行一些重新设计。
#include <tuple>
struct A { int foo; char bar; };
int main() {
A a{1, 'a'};
std::tuple var{&A::foo, &A::bar};
// use var to get/print selected members
std::apply([&a](auto ...field){ (std::cout << ... << field); }, var);
}
// prints: 1a
#include <functional>
#include <map>
#include <vector>
#include <variant> // or <any> if this mechanism will need to work for any type
using field_types = std::variant<int, char>; // more types if needed
using access_type = std::function<field_types(const A&)>;
std::map<std::string, access_type> field_mapping{
{"foo", [](const A& a) { return a.foo; }},
{"bar", [](const A& a) { return a.bar; }},
};
int main() {
A a{1, 'a'};
std::vector<std::string> var{"foo", "bar"};
for (auto&& s : var)
{
auto field = field_mapping[s](a);
std::visit([](auto value) { std::cout << value; }, field);
}
}