使用VS2012的静态映射和std :: function的编译器错误

时间:2017-01-04 14:34:05

标签: c++11 visual-studio-2012 boost

我正在尝试使用静态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中的某种Bug /缺失功能。所以我可以通过不使用静态地图来解决这个问题,但是持有地图的对象生命周期很短,地图会一遍又一遍地初始化。任何暗示我如何使用静态地图和VS2012(我必须使用此版本,没有办法改变这个)?

1 个答案:

答案 0 :(得分:0)

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

以下是更新后的代码,我还更新了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;
}