c++ - 使用 std::pairs 数组初始化 std::map 问题(指针错误?)

标签 c++ pass-by-reference stdmap

我想了解如何初始化private 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 thread 也启发了我),这是我的解决方法:

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[] 的错误导致 Mapping 的大小不等于 2。进入 CallbackSelector 类构造函数。您可以通过查看输出来验证这一点:

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

如果有人能发现这个(显然?)简单的错误,我会很高兴。谢谢。

最佳答案

无法仅通过指向数组的指针来确定数组的大小。您可以将大小作为单独的参数传递:

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)。

关于c++ - 使用 std::pairs 数组初始化 std::map 问题(指针错误?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22610161/

相关文章:

java - 不使用 `return` 将值传递给调用者

具有通用键的 C++ std::map 类

c++ - 如何在c++ 20中将指针变量与consteval一起使用?

c++ - 计算二叉搜索树中的唯一值

c++ - DirectX CreateBuffer 内存泄漏

c++ - 交换两个对象的两个属性的值

c++ - 返回 'const' 或非常量引用之间的区别

c++ - 具有 char* 键和 int 值的容器

c++ - 从 map 中删除对象指针时避免内存泄漏

C++根据其模板定义一个类成员类型