【问题标题】:Allocate vector size with list initialization (curly braces)使用列表初始化分配向量大小(大括号)
【发布时间】:2018-11-29 15:04:53
【问题描述】:

我该怎么做相当于:

#include <vector>

size_t bufferSize = 1024 * 1024;
std::vector<unsigned char> buffer(bufferSize, ' ');

使用列表(花括号)初始化?

当我尝试执行以下操作时:

#include <vector>

size_t bufferSize = 1024 * 1024;
std::vector<unsigned char> buffer {bufferSize, ' '};

它错误地将bufferSize 解释为要存储在容器的第一个索引中的值(即调用错误的std::vector 构造函数),并且由于来自unsigned int (size_t) 的无效收缩转换而无法编译) 到unsigned char

【问题讨论】:

  • 你为什么坚持用“花括号初始化”来做这个?
  • @MaxLanghof 嗯,这叫统一初始化。人们可能会认为它应该是初始化对象的首选方式;)
  • @NathanOliver 相关xkcd.com/927
  • @OP 下面是一篇关于 C++ 初始化噩梦的精彩演讲:youtube.com/watch?v=7DTlWPgX6zs
  • @MaxLanghof 因为有些人建议在任何地方使用它,因为它“更安全”(没有最棘手的解析问题)。实际上它更危险。

标签: c++ c++11 list-initialization


【解决方案1】:

简短回答:你没有

这不是统一初始化本身的问题,而是std::initializer_list 的问题。 重载分辨率中有一个special rule,如果使用list-initialization总是优先考虑采用std::initializer_list的构造函数,而不管存在可能需要较少隐式转换的其他构造函数。


我建议使用

std::vector<unsigned char> buffer(bufferSize, ' ');

或者,如果您真的想要使用 list-initialization,请围绕 std::vector 创建您的包装器,该包装器提供构造函数重载来执行正确的操作。

【讨论】:

    【解决方案2】:

    std::vector 的两个相关重载是:

    explicit vector( size_type count, 
                     const T& value = T(),
                     const Allocator& alloc = Allocator()); //(1)
    vector( std::initializer_list<T> init, 
            const Allocator& alloc = Allocator() ); // (2)
    

    这两个重载有明确的含义,其中第二个用于用std::initializer_list的元素初始化向量。

    当使用list-initialization 时,重载解析更喜欢初始化列表构造函数。

    不允许使用list-initialization 进行缩小转换,您正在尝试使用T=unsigned char 创建一个std::vector,但推导出的Tstd::initializer_list 参数是T= unsigned long,这将涉及一个缩小转换(不允许)。

    【讨论】:

      猜你喜欢
      • 2013-08-23
      • 1970-01-01
      • 1970-01-01
      • 2012-11-21
      • 2015-08-01
      • 1970-01-01
      • 2016-12-11
      • 1970-01-01
      • 2015-06-04
      相关资源
      最近更新 更多