在构造函数初始化器中使用map的初始化列表

时间:2017-08-22 11:46:54

标签: c++ c++11 initializer-list member-function-pointers

尝试为成员函数指针创建int映射并在构造函数初始值设定项中初始化它。 像这样:

class X
{
    using STATEFUNC = void(X::*)(int);
public:
    X() : m{ { 1, &setState1 } } {}

    void setState1(int x) { cout << "state1" << endl; }

    void setState2(int x) { cout << "state2" << endl; }


    std::map<int, STATEFUNC> m;
};

我会说这是正确的,但Visual Studio 2017说:

  

错误C2664'std :: map,std :: allocator&gt;&gt; :: map(std :: initializer_list&gt;)':   无法将参数1从“初始化列表”转换为   '的std :: initializer_list&GT;'

     

错误C2276'&amp;':对绑定成员函数的非法操作   表达

当您从成员函数中删除运算符的地址时,第一条错误消息保持不变,但第二条错误消息更改为:

  

错误C3867'X :: setState1':非标准语法;使用'&amp;'创造一个   指向成员的指针

如何在构造函数初始化列表中初始化int到成员函数指针的映射?

2 个答案:

答案 0 :(得分:15)

here answer是解决方法。至于为什么它是修复:原因是你的代码没有创建指向成员的指针。引用n4659(最后的C ++ 17草案,但之前的标准版本说的相同):

max66

  

指向成员的指针仅在显式&amp;使用和它的   操作数是一个未括在括号中的限定ID。 [注意:那   是,表达式&amp;(qualified-id),其中包含qualified-id   在括号中,不形成“指针”类型的表达式   会员”。也不是qualified-id,因为没有隐含的   从非静态成员函数的qualified-id转换为   键入“指向成员函数的指针”,因为它来自左值   函数类型为“指向函数的指针”([conv.func])。 也不是   &amp; unqualified-id指向成员的指针,即使在范围内也是如此   不合格的id。 - 结束说明]

X::setState1是一个合格的ID,但setState1不是。

答案 1 :(得分:10)

尝试

X() : m{ { 1, &X::setState1 } } {}

仅使用&setState1我从g ++获得以下消息错误

  

错误:ISO C ++禁止获取非限定或带括号的非静态成员函数的地址,以形成指向成员函数的指针。说'&amp; X :: setState1'[-fpermissive]

从clang ++中,错误只是

  

错误:在获取其地址时必须明确限定成员函数的名称

- 编辑 -

我的回答解释了如何解决问题。

要理解为什么&X::setState1有效且&setState1没有,请参阅StoryTeller的答案(+1)