首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++ (No C++11)通过std::map回调类getter函数

C++ (No C++11)通过std::map回调类getter函数
EN

Stack Overflow用户
提问于 2014-11-08 01:06:26
回答 2查看 329关注 0票数 0

我正在尝试创建一个解析引擎,以便从C++中的缓冲区(GPB)库中获取数据。我从序列化数据中解析对象,并从Config类中获取一个对象。我想从这个包含数组和多个嵌套对象和引用的config对象中检索数据(请记住GPB)。而不是硬编码:

代码语言:javascript
运行
复制
if command == "config.wireless.0.ap.0.essid":
    return config.wireless(0).ap(0).essid();
else if command == "config.ip"
    return config.ip();

我想为树的每一层创建一张地图:

代码语言:javascript
运行
复制
std::map<std::string, Callback> map;
map["ip"] = config.ip;

然后用适当的映射计算每个令牌(.分隔),以获取回调。

问题/ TRDL;:具有从类到回调的问题映射getter函数。

我的代码:

代码语言:javascript
运行
复制
#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <map>

class AP
{
public:
    AP() : _key(0), _essid("my ssid!") {}
    int key() { return _key; }
    std::string essid() { return _essid; }
private:
    std::string _essid;
    int _key;
};

class Wireless
{
public:
    Wireless() : _key(0)
    {
        AP ap;
        _aps.push_back(ap);
    }
    int key() { return _key; }
    AP &ap(int index) { return _aps[index]; }
private:
    std::vector<AP> _aps;
    int _key;
};

class Config
{
public:
    typedef std::string *(*FnPtr)(void);

    Config() : _ip("10.0.0.1")
    {
        Wireless wireless;
        _wireless.push_back(wireless);
    }

    Wireless &wireless(int index) { return _wireless[index]; }
    std::string ip() { return _ip; }
private:
    std::vector<Wireless> _wireless;
    std::string _ip;
};



void compute(const std::string &cmd, Config &config)
{
    std::map<std::string, Config::FnPtr> fn_map;
    fn_map["ip"] = config.ip;

    std::cout << fn_map[cmd]() << std::endl;
}

int main(int argc, char* argv[])
{
    Config config;
    std::string cmd = "ip";

    compute(cmd, config);

    return 0;
}

不幸的是,如果不使用C++11 std::function/bind,我如何才能让这种行为正常工作呢?有人提到C++不允许反射(我正在尝试做的事情),所以希望有一种方法来解决这个问题。

此外,如果有人知道SNMP如何将字符串mywireless.0.interface.1.ip转换为适当的函数以获取我感兴趣的值,那么我将使用类似于SNMP的语法。

EN

Stack Overflow用户

发布于 2014-11-08 01:30:53

你的问题:

代码语言:javascript
运行
复制
std::map<std::string, Config::FnPtr> fn_map;
    fn_map["ip"] = config.ip;

Config::FnPtr是一个:

代码语言:javascript
运行
复制
typedef std::string *(*FnPtr)(void);

用英语描述,这是“指向不带参数并返回指向std::string的指针的函数的指针”。

"config.ip“是”一个指向类Config的成员方法的指针,该方法不接受参数并返回一个std::string“。

这两者是不一样的,因此你的错误。

这并不仅仅是因为您可能意味着您的typedef是"typedef std::string (*FnPtr)(void)“。即使你解决了这个问题,这也是行不通的。这是因为你将拥有:

“一个不带参数并返回指向std::string的指针的函数。”

“指向类Config的成员方法的指针,它不接受参数并返回std::string。”

两者仍然不一样,其中一个不能分配给另一个。

那么,你能做什么?这取决于你的确切意图。我猜你可能想要这样的东西:

首先,更改typedef:

代码语言:javascript
运行
复制
typedef std::string (Config::*FnPtr)(void);

这将FnPtr声明为“一个指向类Config的成员方法的指针,该方法不带任何参数,并返回一个std::string”。

然后,重写计算()方法:

代码语言:javascript
运行
复制
void compute(const std::string &cmd, Config &config)
{
    std::map<std::string, Config::FnPtr> fn_map;
    fn_map["ip"] = &Config::ip;

    std::cout << (config.*fn_map[cmd])() << std::endl;
}

&Config::ip的英文描述是“指向名为ip的类Config成员的指针”。这个成员恰好是“一个不带参数并返回std::string的方法”。

表达式(config.*fn_map[cmd])()可以用英语描述为:访问由表达式"fn_mapcmd“指定的名为config的类实例的成员。

根据我给你的描述,你应该能够自己找出为什么会起作用。

票数 2
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26812579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档