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

using map's initializer list inside constructor initializer

正在尝试创建 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 年说:

Error C2664 'std::map,std::allocator>>::map(std::initializer_list>)': cannot convert argument 1 from 'initializer list' to 'std::initializer_list>'

Error C2276 '&': illegal operation on bound member function expression

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

Error C3867 'X::setState1': non-standard syntax; use '&' to create a pointer to member

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

试试

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

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

error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&X::setState1’ [-fpermissive]

来自 clang++ 的错误只是

error: must explicitly qualify name of member function when taking its address

-- 编辑--

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

要了解为什么 &X::setState1 有效而 &setState1 无效,请参阅 StoryTeller 的回答 (+1)

by max66 是解决方法。至于为什么它是修复:原因是您的代码没有创建指向成员的指针。引用 n4659(最新的 C++17 草案,但之前的标准修订版也是如此):

[expr.unary.op/4]

A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses. [ Note: That is, the expression &(qualified-id), where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member”. Neither does qualified-id, because there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” ([conv.func]). Nor is &unqualified-id a pointer to member, even within the scope of the unqualified-id's class.  — end note ]

X::setState1是合格的id,setState1不是。