首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在条件下从三种不同的地图中选择

在条件下从三种不同的地图中选择
EN

Stack Overflow用户
提问于 2017-03-21 22:31:10
回答 2查看 91关注 0票数 1

我有3种不同的C++映射声明。

代码语言:javascript
复制
map<string, string> map1; 
map<string, int> map2; 
map<string, double> map3; 

我想要一张地图,视情况而定。比方说

代码语言:javascript
复制
if (map_value == "map1") { default_map = map1; } 
else if (map_value == "map2") { default_map = map2; } 
else { default_map = map3; } 

我的问题是,我不知道如何在C++中声明可以根据条件更改的C++。我期望类似于map<Object,Object> default_map在C++中的声明。

编辑。我选择stringintdouble作为假设对象。实际的map1map2map3存储函数指针。根据映射中的值,我调用不同的函数。函数签名是相同的,但是这些函数指针来自不同的类。本质上,class Avoid funcA(string);class Bvoid funcA(string);class Cvoid funcA(string);funcA根据类实现不同。

任何帮助都是非常感谢的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-21 23:47:09

鉴于你在评论中所作的澄清,我可以提出以下建议:

代码语言:javascript
复制
std::function<R(K, T1, T2, T3)> look_up_and_call;

X x;
Y y;
Z z;

if (map_value == "map1") {
  look_up_and_call =
      [&x, &map1](K key T1 t1, T2 t2, T3 t3) { return (x.*map1[key])(t1, t2, t3); }
} else if (map_value == "map2") {
  look_up_and_call =
      [&y, &map2](K key T1 t1, T2 t2, T3 t3) { return (y.*map2[key])(t1, t2, t3); }
} else {
  look_up_and_call =
      [&z, &map3](K key T1 t1, T2 t2, T3 t3) { return (z.*map3[key])(t1, t2, t3); }
}

现在,对于任何给定的映射键key,您可以按如下方式调用绑定函数:

代码语言:javascript
复制
R result = look_up_and_call(key, arg1, arg2, arg3);

我已经稍微简化了代码,例如,我们假设map元素总是非空成员函数指针。您可以调整此方案以允许其他类型的指针,而真正的代码可能会处理密钥不存在的问题。您还可以编写用于将元素添加到映射中的类似函数。

票数 1
EN

Stack Overflow用户

发布于 2017-03-21 22:53:40

C++有足够强的输入能力,您将很难完成您在这里要求的操作。

我可以看到几个明显的可能性。一种方法是使用类似于Boost变体的东西来存储值:

代码语言:javascript
复制
std::map<string, boost::variant<string, int, double> > mapN;

这将允许您将stringintdouble中的任何一个与给定的字符串作为键进行关联。变体类型基本上是一个受歧视的联合--也就是说,它可以存储任何一种指定的类型,并且有一个字段来告诉在任何特定实例中存在哪一个类型。

另一种可能是拥有一个看起来像所有三种值类型都重载的单一函数,这样您就可以在调用站点上拥有统一的代码:

代码语言:javascript
复制
void save_map(std::string const &key, std::string const & val) { 
    map1[key] = val;
}

void save_map(std::string const &key, int val) { 
    map2[key] = val;
}

void save_map(std::string const &key, double val) { 
   map3[key] = val;
}

这使得像save_map("foo", bar);这样的代码可以工作,因为bar是三种指定类型中的任何一种(加上隐式转换)。但是,请注意,最初看来最明显的检索值的设计是行不通的。特别是,您不能在返回类型上超载,所以您不能使用以下内容:

代码语言:javascript
复制
std::string get_map(std::string);
int get_map(std::string);
double get_map(std::string);

不能在返回类型上重载,因此必须将重载类型作为参数传递:

代码语言:javascript
复制
void get_map(std::string const &key, string &dest);
void get_map(std::string const &key, int &dest);
void get_map(std::string const &key, double &dest);

至于这些(或其他可能性)中的哪一种是有意义的:这将取决于你真正想要实现的目标--这是你还没有告诉我们足够多的有意义的答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42939407

复制
相关文章

相似问题

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