C++使用模板和继承创建函数映射
C++ Creating function map using templates and inheritance
我正在尝试使用模板创建一个通用函数映射。其思想是从这个具有特定函数指针类型的通用模板类中继承。我可以在全局工作区中注册一个函数,但我更愿意将所有函数一起收集到派生类中,并将它们注册到构造函数中。我想我差不多到了,但我遇到了一个编译错误。这是我代码的精简版本:
#include <iostream>
#include <string>
#include <map>
#include <cassert>
using namespace std;
int f(int x) { return 2 * x; }
int g(int x) { return -3 * x; }
typedef int (*F)(int);
// function factory
template <typename T>
class FunctionMap {
public:
void registerFunction(string name, T fp) {
FunMap[name] = fp;
}
T getFunction(string name) {
assert(FunMap.find(name) != FunMap.end());
return FunMap[name];
}
private:
map<string, T> FunMap;
};
// specific to integer functions
class IntFunctionMap : public FunctionMap<F> {
public:
int f2(int x) { return 2 * x; }
int g2(int x) { return -3 * x; }
IntFunctionMap() {
registerFunction("f", f); // This works
registerFunction("f2", f2); // This does not
}
};
int main()
{
FunctionMap<F> fmap; // using the base template class directly works
fmap.registerFunction("f", f);
F fun = fmap.getFunction("f");
cout << fun(10) << endl;
return 0;
}
我得到的错误是:
templatefunctions.cpp: In constructor ‘IntFunctionMap::IntFunctionMap()’:
templatefunctions.cpp:33: error: no matching function for call to ‘IntFunctionMap::registerFunction(const char [3], <unresolved overloaded function type>)’
templatefunctions.cpp:15: note: candidates are: void FunctionMap<T>::registerFunction(std::string, T) [with T = int (*)(int)]
Juan的答案是正确的:成员函数有一个隐式的第一个参数,它是指向它们所属类型的指针。代码编译失败的原因是映射支持类型为int (*)(int)
的函数指针,但f2的类型是int (IntFunctionMap::*)(int)
。
在这里显示的特定情况下,可以使用实现类型擦除的std::function
将自由函数和成员函数表示为同一类型。然后你就可以做你想做的事情了。注意:这需要C++11。
#include <iostream>
#include <string>
#include <map>
#include <cassert>
#include <function>
#include <bind>
using namespace std;
int f(int x) { return 2 * x; }
int g(int x) { return -3 * x; }
typedef std::function<int (int)> F;
// function factory
template <typename T>
class FunctionMap {
public:
void registerFunction(string name, T fp) {
FunMap[name] = fp;
}
T getFunction(string name) {
assert(FunMap.find(name) != FunMap.end());
return FunMap[name];
}
private:
map<string, T> FunMap;
};
// specific to integer functions
class IntFunctionMap : public FunctionMap<F> {
public:
int f2(int x) { return 2 * x; }
int g2(int x) { return -3 * x; }
IntFunctionMap() {
registerFunction("f", f); // This works
registerFunction("f2", std::bind(&f2, this, _1)); // This should work, too!
}
};
int main()
{
FunctionMap<F> fmap; // using the base template class directly works
fmap.registerFunction("f", f);
F fun = fmap.getFunction("f");
cout << fun(10) << endl;
return 0;
}
相关文章:
- 如何创建从同一类继承的不同对象的向量
- 如果'C'公开继承'B',B 私下继承'A',为什么我不能在"C"中创建"A"的对象?
- 如何创建没有特定定义的随机分布?uniform_int_distribution是从其他类继承的吗?
- 从抽象类继承以创建另一个抽象类时,我应该重新声明所有虚函数吗?
- 了解虚拟继承类 vtables 和 vptr 创建
- 如何从继承的父类创建unique_ptr
- 创建一个具有两个可能继承的类
- 如何创建一个继承自 std::vector 的类
- 是否有可能有一个派生类继承最终函数但创建相同的函数(而不是重写)
- 创建一系列超类的指针,以分配继承的类
- 如何创建从版本继承的CMAKE配置类型
- 动态创建一个继承的类,使用STD :: MAP使用基类指针访问
- 创建一个函数,该函数返回具有现有类继承的不同类型
- 如何允许一个类由另一个类创建而不使用'friend'但允许继承?
- 如何创建一个新类来继承 ostream 并将其用作 cout 但带有锁定
- 无法创建两个从 std::logic_error 继承的自定义异常类
- 如何在Qt Creator中从继承的类自动创建虚拟方法
- 在构造函数 QT 创建器(继承类)中传递默认参数
- 如果对象是堆栈创建的(包括继承的类型),是否可以发出编译错误
- C++使用模板和继承创建函数映射