我正在尝试使用静态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(我必须使用此版本,没有办法改变这个)?
答案 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;
}