2017-01-04 6 views
0

enumをキーとし、std::functionを値としてスタティックstd::mapを使用しようとしています。静的マップは、ブースト1.52からboost::assign::map_list_ofを使用して初期化されます。 VS2012はC++ 11の初期化リストを知らないので、私はこれを行うためにブーストを使用しています。私のコードはここwandboxVS2012を使用した静的マップとstd ::関数のコンパイラエラー

に素晴らしい作品私のコードは

#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/Missing機能の一種だと思います。だから私は静的なマップを使用しないでこれを解決することができますが、マップを保持するオブジェクトの寿命はかなり短く、マップは何度も何度も初期化されます。静的なマップとVS2012でこれをどうすればいいのか(私はこのバージョンを使わなければならない、これを変更する方法はない)

+0

を更新しましたか? –

+0

これは実際には悪い考えではありません。私は今日これを試して、報告して、感謝します! –

+0

@DanMašekboost ::関数で動作します。どうもありがとうございました。これを回答として提供すれば、私はそれを喜んで受け入れます! –

答えて

0

boost::functionDan Masekとして提案しました。ここで

が更新されたコードであり、私はまた、あなたがおそらく `ブースト:: 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; 
} 
関連する問題