You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将字符串向量传递给宏以访问C++类成员变量?

通过字符串变量访问C++类成员的编译错误及解决方法

问题代码

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

编译错误

error: expected unqualified-id before ‘*’ token
   25 |   std::cout << DECLARE(d, *it) << std::endl;

错误原因

宏是预处理阶段执行的工具,只能处理编译期确定的字面量,无法识别运行时的变量:

  • #X 是宏的字符串化操作,会把参数X直接转换成字符串字面量,所以DECLARE(d, *it)会被预处理成 "d"->*it。
  • 字符串字面量不能用->访问成员,且*it是运行时才会确定值的字符串变量,预处理阶段根本无法解析它的内容,最终生成非法语法导致编译报错。

解决方案

C++是静态类型语言,无法直接通过运行时字符串访问类成员,需要手动建立字符串到成员的映射关系,以下是两种可行方案:

方案1:使用成员指针+变体类型映射

利用std::unordered_map存储字符串到成员指针的映射,用std::variant兼容不同类型的成员:

#include <iostream>
#include <vector>
#include <unordered_map>
#include <variant>

class dut{
public:
    int clock;
    double reset;
    dut(int a, int b) : clock(a), reset(b) {}
    ~dut() = default;
};

int main(int argc, char **argv){
    dut *d = new dut(4, 5);
    std::vector<std::string> var = {"clock", "reset"};
    
    // 建立字符串到成员指针的映射
    std::unordered_map<std::string, std::variant<int*, double*>> member_map = {
        {"clock", &d->clock},
        {"reset", &d->reset}
    };

    for(const auto& name : var){
        auto map_it = member_map.find(name);
        if(map_it != member_map.end()){
            // 访问并打印对应成员的值
            std::visit([](auto ptr){ std::cout << *ptr << std::endl; }, map_it->second);
        }
    }

    delete d;
    return 0;
}

方案2:直接判断字符串(适合成员数量少的场景)

如果类成员数量不多,直接通过if-else判断字符串名称,直接访问成员:

#include <iostream>
#include <vector>

class dut{
public:
    int clock;
    double reset;
    dut(int a, int b) : clock(a), reset(b) {}
    ~dut() = default;
};

int main(int argc, char **argv){
    dut *d = new dut(4, 5);
    std::vector<std::string> var = {"clock", "reset"};

    for(const auto& name : var){
        if(name == "clock"){
            std::cout << d->clock << std::endl;
        } else if(name == "reset"){
            std::cout << d->reset << std::endl;
        }
    }

    delete d;
    return 0;
}

内容的提问来源于stack exchange,提问作者Ben Eslami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:35:28