使用 VS2012 的静态地图和 std::function 编译器错误

Compiler Error with static map and std::function using VS2012

我正在尝试使用静态 std::map,其中 enum 作为键,std::function 作为值。静态地图使用来自 boost 1.52 的 boost::assign::map_list_of 初始化。我正在使用 boost 来执行此操作,因为 VS2012 不知道 c++11 初始化程序列表。我的代码在 wandbox

上运行良好

这是我的代码的样子

#include <iostream>
#include <string>
#include <map>
#include <functional>
#include <utility>

#include <boost/assign/list_of.hpp>

namespace ba = boost::assign;

class Foo
{
    public:    
    enum class MapKeys
    {
        Key1,
        Key2
    };

    typedef std::map<Foo::MapKeys, std::function<bool(Foo*, int i)>> fooMap;

    bool key_based_action(Foo::MapKeys m, int i) {
        return((Foo::myMap.at(m))(this, i));
    }

    private:

    static const Foo::fooMap myMap ;

    bool key1_handler(int i) {
        if (i > 0) {
            return true;
        }
        return false;
    }
    bool key2_handler(int i) {
        if (i < 0) {
            return true;
        }
        return false;
    }

};

//const Foo::fooMap Foo::myMap = 
//{
//    {Foo::MapKeys::Key1, std::mem_fn(&Foo::key1_handler)},
//    {Foo::MapKeys::Key2, std::mem_fn(&Foo::key2_handler)}
//};

const Foo::fooMap Foo::myMap = 
    ba::map_list_of(Foo::MapKeys::Key1, std::mem_fn(&Foo::key1_handler))
    (Foo::MapKeys::Key2, std::mem_fn(&Foo::key2_handler));

int main(void) 
{
    Foo f;
    if(f.key_based_action(Foo::MapKeys::Key1, 1))
        std::cout << "Key1 returned true" << std::endl;
    if(f.key_based_action(Foo::MapKeys::Key2, 1))
        std::cout << "Key2 returned true" << std::endl;
    return 0;
}

错误信息:

1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xrefwrap(518): error C2248: "std::_Callable_base<_Ty,_Indirect>::operator =": Kein Zugriff auf private Member, dessen Deklaration in der std::_Callable_base<_Ty,_Indirect>-Klasse erfolgte.
1>         with
1>          [
1>              _Ty=bool (__thiscall Foo::* )(int),
1>              _Indirect=false
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xrefwrap(331): Siehe Deklaration von 'std::_Callable_base<_Ty,_Indirect>::operator ='
1>          with
1>          [
1>              _Ty=bool (__thiscall Foo::* )(int),
1>              _Indirect=false
1>          ]
1>          Diese Diagnose trat in der vom Compiler generierten Funktion "std::_Callable_pmf<_Ty,_Memty> &std::_Callable_pmf<_Ty,_Memty>::operator =(const std::_Callable_pmf<_Ty,_Memty> &)" auf.
1>          with
1>          [
1>              _Ty=bool (__thiscall Foo::* )(int),
1>              _Memty=Foo
1>          ]

上面写着类似std::_Callable_base<_Ty,_Indirect>.

中声明的私有成员没有访问权限之类的话

因为这适用于 gcc / clang 和 visual studio 的更高版本(使用 VS2015CE 和 boost 1.63 测试)我想这是 VS2012 中的某种错误/缺失功能。所以我可以通过不使用静态地图来解决这个问题,但是持有地图的对象生命周期很短,而且地图会被一遍又一遍地初始化。任何提示我如何使用静态地图和 VS2012 执行此操作(我必须使用此版本,无法更改此版本)?

对我来说,这个问题的答案是按照 Dan Masek 的建议使用 boost::function

这是更新后的代码,我也更新了 wandbox 示例

#include <iostream>
#include <string>
#include <map>
#include <utility>

#include <boost/function.hpp>
#include <boost/assign/list_of.hpp>

namespace ba = boost::assign;

class Foo
{
    public:    
    enum class MapKeys
    {
        Key1,
        Key2
    };

    typedef std::map<Foo::MapKeys, boost::function<bool(Foo*, int i)>> fooMap;

    bool key_based_action(Foo::MapKeys m, int i) {
        return((Foo::myMap.at(m))(this, i));
    }

    private:

    static const Foo::fooMap myMap ;

    bool key1_handler(int i) {
        if (i > 0) {
            return true;
        }
        return false;
    }
    bool key2_handler(int i) {
        if (i < 0) {
            return true;
        }
        return false;
    }

};

//const Foo::fooMap Foo::myMap = 
//{
//    {Foo::MapKeys::Key1, std::mem_fn(&Foo::key1_handler)},
//    {Foo::MapKeys::Key2, std::mem_fn(&Foo::key2_handler)}
//};

const Foo::fooMap Foo::myMap = 
    ba::map_list_of(Foo::MapKeys::Key1, &Foo::key1_handler)
    (Foo::MapKeys::Key2, &Foo::key2_handler);

int main(void) 
{
    Foo f;
    if(f.key_based_action(Foo::MapKeys::Key1, 1))
        std::cout << "Key1 returned true" << std::endl;
    if(f.key_based_action(Foo::MapKeys::Key2, 1))
        std::cout << "Key2 returned true" << std::endl;
    return 0;
}