我正在尝试了解如何正确初始化私有const std::map
。我已经研究了this众所周知的话题,但没有一个答案适合我,因为我被迫使用旧的gcc和boost版本(gcc 4.4,boost 1.41 - > C ++ 11的功能有限, boost::asign::map_list_of does not compile)而且,我不想使用类成员函数进行std :: map初始化,因为在构造对象时需要在类外部执行此操作。
但是,std::map
的重载构造函数接受了两个迭代器(this线程也启发了我),这是我的解决方法:
template <typename Arg, typename Callback>
class CallbackSelector
{
private:
const std::map<Arg, Callback> Mapping;
public:
CallbackSelector(std::pair<Arg, Callback> _Mapping[]):
Mapping(_Mapping, _Mapping + sizeof(_Mapping)/sizeof(std::pair<Arg, Callback>))
{
//BOOST_ASSERT(sizeof _Mapping)/(sizeof (std::pair<Arg, Callback>)) == 2);
std::cout << "sizeof _Mapping " << sizeof _Mapping << std::endl;
std::cout << "sizeof (std::pair<Arg, Callback>) " << sizeof (std::pair<std::string, boost::function<void(void)> >) << std::endl;
};
};
void PamEvent() {}
void DefaultEvent() {}
int main(int argc, char** argv)
{
std::pair<std::string, boost::function<void(void)> > _Mapping[] =
{
std::make_pair("pam:", boost::bind(&PamEvent)),
std::make_pair("none", boost::bind(&DefaultEvent))
};
std::cout << "sizeof _Mapping " << sizeof _Mapping << std::endl;
std::cout << "sizeof (std::pair<Arg, Callback>) " << sizeof (std::pair<std::string, boost::function<void(void)> >) << std::endl;
CallbackSelector<std::string, boost::function<void(void)> > Selector(_Mapping);
}
(The full executable version of this example)
如果我使用BOOST_ASSERT宏取消注释该行,则不会编译此代码,因为由于将std::pair<std::string, boost::function<void(void)> > _Mapping[]
传递给CallbackSelector类构造函数的错误,Mapping的大小不等于2。您可以通过查看输出来验证这一点:
sizeof _Mapping 80 //in the int main()
sizeof (std::pair<Arg, Callback>) 40
sizeof _Mapping 8 //in the CallbackSelector constructor
sizeof (std::pair<Arg, Callback>) 40 //the array size has decreased tenfold
如果有人能找到这个(显然是?)简单的错误,我会很高兴。谢谢。
答案 0 :(得分:2)
只有指向它的指针才能确定数组的大小。您可以将大小作为单独的参数传递:
CallbackSelector(std::pair<Arg, Callback> mapping[], size_t size) :
Mapping(mapping, mapping + size)
或推断它为模板参数:
template <size_t size>
CallbackSelector(std::pair<Arg, Callback> (&mapping)[size]) :
Mapping(mapping, mapping + size)
或者,在C ++ 11或更高版本中,您可以使用initializer_list
参数
CallbackSelector(std::initializer_list<std::pair<Arg, Callback>> mapping) :
Mapping(mapping.begin(), mapping.end())
// Usage example
CallbackSelector<std::string, boost::function<void(void)> > selector {
{arg1, callback1},
{arg2, callback2}
};
(注意:我冒昧地重命名_Mapping
,reserved name,你不应该使用它。)