c++ - 从 unordered_multimap 中调用另一个类的函数?
问题描述
这与我的上一篇文章有关,您可以在此处找到:Creating an unordered_map of std::functions with any arguments。我现在已经开始并将其扩展到课堂。所以假设我有三个不同的课程。这些类都有不同的方法,除了getVariable()
和setVariable(int)
。所以对于这个例子,我们将对它们进行分类ClassA
,ClassB
和ClassC
。
我还有一个基类,我想将其用作我的驱动程序。本质上,如果我想在 和 之间设置变量ClassA
,ClassC
我会调用基类的setVariable
函数。
#ifndef BASE_CLASS_HPP
#define BASE_CLASS_HPP
#include <unordered_map>
#include <functional>
#include <utility>
#include <string>
#include <any>
template<class A, class B>
class BaseClass
{
public:
BaseClass() { bindThem(); }
std::pair<int,int> getValue()
{
// return classA and ClassB's values
}
void setValue(int newVal)
{
auto iter = functions.equal_range("setValue");
std::any_cast<void(*)(int)>(mapIter->second)(newVal);
}
private:
std::unordered_multimap<std::string,std::any> functions;
void bindThem()
{
functions.emplace("setValue",&A::setValue);
functions.emplace("setValue",&B::setValue);
functions.emplace("getValue",&A::getValue);
functions.emplace("getValue",&B::getValue);
}
};
然后我主要有:
#include <iostream>
#include "baseClass.hpp"
#include "classA.hpp"
#include "classB.hpp"
#include "classC.hpp"
int main()
{
ClassA a;
ClassB b;
ClassC c;
c.setValue(20);
BaseClass<ClassA,ClassB> base1;
BaseClass<ClassA,ClassC> base2;
base1.setValue(15);
auto values = base1.getValues();
}
我可以将这些功能与我的地图一起放置,但是,当我尝试这样做时,any_cast
我没有得到任何回报。我也试过:
std::any_cast<void(A::*)(int)>(mapIter->second)(newVal);
但这也给了我一个必须使用 .* 或 ->* 的编译器错误,我已经尝试了一切来编译它,但我真的不知道我做错了什么。我也意识到,如果我这样调用它,那么我将无法访问 B 的setVariable
函数,因为我正在使用A's
命名空间。
无论如何我可以让它按我想要的方式工作吗?我实际上是在尝试修改这些类的值,而不必复制这些类,而是直接从这个驱动程序中修改它们。
解决方案
我仍然不太了解这种结构的目的,但这里有一个选项如何使它至少编译:
#include <unordered_map>
#include <functional>
#include <utility>
#include <string>
#include <any>
template<class A, class B>
class BaseClass
{
public:
BaseClass() { bindThem(); }
std::pair<int,int> getValue()
{
auto range = functions.equal_range("getValue");
return
{
(a.*std::any_cast<int(A::*)()>(*range.first))(),
(b.*std::any_cast<int(B::*)()>(*range.second))()
};
}
void setValue(int newVal)
{
auto range = functions.equal_range("setValue");
(a.*std::any_cast<void(A::*)(int)>(*range.first))(newVal);
(b.*std::any_cast<void(B::*)(int)>(*range.second))(newVal);
}
private:
std::unordered_multimap<std::string,std::any> functions;
void bindThem()
{
functions.emplace("setValue",&A::setValue);
functions.emplace("setValue",&B::setValue);
functions.emplace("getValue",&A::getValue);
functions.emplace("getValue",&B::getValue);
}
A a;
B b;
};
class ClassA
{
public:
void setValue(int){}
int getValue() {return 0;}
};
class ClassB
{
public:
void setValue(int){}
int getValue() {return 1;}
};
int main()
{
BaseClass<ClassA, ClassB> x;
x.setValue(3);
auto i = x.getValue();
}
请注意几点:
- 我已经向 BaseClass 添加了成员,因为要调用成员函数,您需要调用一个对象。
- 我使用 from 范围的第一个和最后一个迭代器
equal_range
,但该范围内元素的顺序是实现定义的。因此,为了使事情正常工作,您需要注意区分哪个容器元素对应于 classA
以及哪个容器元素对应于 classB
。
推荐阅读
- android - 应用程序已在 android 模拟器中停止
- django - 如何从网页 URL http://dev.myapplication.io:8000 中删除端口 8000。我希望我的网址是 http://dev.myapplication.io
- element - 无容器自定义元素上的 Aurelia 自定义属性,未获取元素
- sql - 获取具有条件的关联记录数
- pandas - set_index 和 groupby 如何协同工作?
- docker - osixia/openldap SSL/TLS 问题
- python - 使用 OpenCV 和 Python 将图像的分割部分替换为其他图像
- xamarin.forms - OneSignal 通知扩展,错误找不到任何可用的配置文件
- swift - 在不使用 segue 的情况下向后传递数据?
- java - 如何在不轮询的情况下从 Java Web 应用程序获取响应?