模板化仿函数哈希表

时间:2017-07-06 09:38:07

标签: c++11 hashtable functor

我想为成员模板化仿函数创建一个hastable,我解释一下。 这是我的例子,它不起作用:

#include <iostream>    
#include <unordered_map>

using namespace std;
class MyFirstClass
{
    int i_;

public:
    MyFirstClass(): i_(0) {}

    void setI(int i) { i_ = i; }
    int getI() { return i_; }
};

class MySecondClass
{
    bool b_;

public:

    MySecondClass(): b_(0) {}

    void setB(bool b) { b_ = b; }
    bool getB() { return b_; }
};

template<class X, void (X::*p)()>
class MyFunctor
{
    X& _x;
public:
    MyFunctor(X& x) : _x( x ) {}
    void operator()() const { (_x.*p)(); }
};

int main(int argc, char *argv[])
{
    unordered_map<string,MyFunctor> myHashTable;

    MyFirstClass first;
    MyFirstClass second;

    myHashTable["int"] = first::setI;
    myHashTable["bool"] = second::setB;

    //
    string key = "bool";
    int value = 1;

    myHashTable[key](value);

    return 0;
}

我有多个班级都有自己的二传手。我希望能够感谢has表和命令{string,int}更改相应类的值。

以前的代码目前无法使用,我被卡住了。

1 个答案:

答案 0 :(得分:0)

您的代码存在一些问题。

首先,从您的示例中unordered_map<string,MyFunctor>未命名类型,因为MyFunctor未命名类型。您可以使用虚拟operator()创建非模板基类,然后让MyFunctor继承它。

其次,您没有使用兼容的方法指针,MyFirstClass::setIMySecondClass::setB都采用参数。

第三,与第一个相关,您必须在从类模板构造对象时指定模板参数。 (直到c ++ 17的课程模板演绎指南)。你也有不合语法的语法我假设试图在方法指针模板参数旁边指定MyFunctor构造函数的对象参数。

你会有像

这样的东西
class MyFunctorBase {
    virtual void operator()(void * i) const = 0;
}

template<class T, class X, void (X::*p)(T)>
class MyFunctor : public MyFunctorBase 
{
    X& _x;
public:
    MyFunctor(X& x) : _x( x ) {}
    void operator()(void * i) const override { (_x.*p)(*static_cast<T*>(i)); }
};

int main(int argc, char *argv[])
{
    unordered_map<string,shared_ptr<MyFunctorBase>> myHashTable;

    MyFirstClass first;
    MyFirstClass second;

    myHashTable["int"] = make_shared<MyFunctor<int, MyFirstClass, &MyFirstClass::setI>>(first);
    myHashTable["bool"] = make_shared<MyFunctor<bool, MySecondClass, &MySecondClass::setB>>(second);


    //
    string key = "bool";
    bool value = true;

    (*myHashTable[key])(static_cast<void *>(&value));

    return 0;
}

或者,更容易使用现有的std::function,它可以为您做到这一点

int main(int argc, char *argv[])
{
    unordered_map<string,function<void(void *)>> myHashTable;

    MyFirstClass first;
    MyFirstClass second;

    myHashTable["int"] = [first](void * i) { first.setI(*static_cast<int *>(i)); };
    myHashTable["bool"] = [second](void * i) { second.setB(*static_cast<bool *>(i)); };


    //
    string key = "bool";
    bool value = true;

    myHashTable[key](static_cast<void *>(&value));

    return 0;
}