从 unordered_multimap 中调用另一个类的函数?
Posted
技术标签:
【中文标题】从 unordered_multimap 中调用另一个类的函数?【英文标题】:Calling a function from another class from within an unordered_multimap? 【发布时间】:2019-04-05 02:58:10 【问题描述】:这与我的上一篇文章有关,您可以在这里找到: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);
;
然后我在 main:
#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
命名空间。
无论如何我可以让它按我想要的方式工作吗?我实际上是在尝试修改这些类的值,而不必复制这些类,而是直接从这个驱动程序中修改它们。
【问题讨论】:
您正在尝试调用成员函数,但我无法理解它们应该被调用的对象。 @DmitryGordon 我正在尝试调用我作为模板传入的类的成员函数。我想这就是你要问的? 要调用成员函数,您需要指定要调用的对象的实例。例如:调用ClassA::setValue
你需要ClassA
类的实例。 a.setValue(15)
在底层转换为 A::setValue(&a, 15)。因此,要调用此值,您需要为函数指针提供两个参数
@DmitryGordon 我明白这一点。但是,我想弄清楚如何使用std::any_cast
以这种特定方式访问成员函数。理论上,目标是使用多映射来访问键,并一举修改属于该键的值。但是,演员表不工作,我不知道如何让它工作。
【参考方案1】:
我仍然不太明白这种结构的目的,但这里有一个选项如何使它至少编译:
#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 添加了成员,因为要调用成员函数,您需要调用一个对象。
我正在使用
equal_range
范围内的第一个和最后一个迭代器,但该范围内元素的顺序是实现定义的。因此,为了使事情顺利进行,您需要注意区分哪个容器元素对应于类A
,以及哪个容器元素对应于类B
。
【讨论】:
以上是关于从 unordered_multimap 中调用另一个类的函数?的主要内容,如果未能解决你的问题,请参考以下文章
在 boost::unordered_multimap 中循环遍历 equal_range
保证 std::unordered_multimap 中的键唯一性
对 unordered_multimap 键进行平均的更好方法是啥?
在 unordered_multimap 中准确地迭代每个键一次的有效方法