静态映射到函数指针

时间:2017-05-29 12:31:48

标签: c++

我正在尝试在C ++中实现类似于C#setter的东西。这个想法是拥有一个类属性的枚举和相应的setter。我的代码如下所示。我将在类定义中编写实现。

#include <string>
#include <map>

enum ClassProperties
{
    Id, Name
};

class MyClass
{
public:
    int Id;
    std::string Name;

    public void SetValue(ClassProperties c, std::string value){
            setters[c](this, value);

   }

private:
    typedef void (* t_setter)(MyClass *, std::string);

    static void set_id(MyClass * obj, std::string value) {
         obj->Id = std::stoi(value);
    }
    static void set_name(MyClass * obj, std::string value) {
         obj->Name = value;
    }

    static std::map<ClassProperties, t_setter> setters = {{ClassProperties:: Id, set_id}, {ClassProperties::Name, set_name}};


};

我希望这段代码能够选择相应的函数并调用它,但我在最后一行收到错误

error: in-class initialization of static data member ‘std::map<ClassProperties, void (**)(MyClass*, std::basic_string<char>)> MyClass::setters’ of incomplete type

error: could not convert ‘{{Id, MyClass::set_id}, {Name, MyClass::set_name}}’ from ‘<brace-enclosed initializer list>’ to ‘std::map<ClassProperties, void (**)(MyClass*, std::basic_string<char>)>’

我做错了什么?

1 个答案:

答案 0 :(得分:2)

setters的初始化错误。您应该按如下方式进行更改:

1)从班级主体中删除该行:

static std::map<ClassProperties, t_setter> setters =
    {{ClassProperties:: Id, set_id}, {ClassProperties::Name, set_name}};

2)在类体中添加静态成员的适当初始化:

std::map<ClassProperties, MyClass::t_setter> MyClass::setters = {
        { ClassProperties::Id, &MyClass::set_id },
        { ClassProperties::Name, &MyClass::set_name }
};

此外,您必须在SetValue函数之前删除 public 说明符。

wandbox example