将字符串值向量传递给宏问题

问题描述 投票:0回答:3

我尝试通过向量中的名称访问类的变量。 这是我的代码:

#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;

有人可以帮我吗?

我尝试通过存储在向量中的名称来访问类的变量。

但问题是如何将字符串变量传递给宏。

c++ macros
3个回答
2
投票

如果你喜欢打印

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

这个库有一些限制,比如没有字段名称。


2
投票

哦,我想我知道你想要做的,打印

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
使用指针和动态分配。


0
投票

在当前的 C++ 中,您想要实现的目标并不容易。也许几年后我们将在 C++ 中实现 reflection - 那么这将很容易实现。

您根本无法轻松获取仅具有运行时名称的对象成员字段。

但是,仍然有一些选择,但很可能需要对您的项目进行一些重新设计。

  1. 使用指向成员的指针的元组
#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

  1. 设计您自己的从字符串到对成员的某些访问的映射,使用 std::function:
#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);
   }
}

© www.soinside.com 2019 - 2024. All rights reserved.