使用列表初始化(花括号)分配向量大小

19

我该如何实现以下代码的等效功能:

#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 的非法缩小转换而无法编译。

10
为什么您坚持使用“花括号初始化”进行此操作? - Max Langhof
6
@MaxLanghof,这被称为统一初始化。人们可能会认为这应该是初始化对象的首选方式 ;) - NathanOliver
4
@NathanOliver 相关 https://xkcd.com/927/ - llllllllll
2
@OP 这里有一个非常好的关于 C++ 初始化的演讲:https://www.youtube.com/watch?v=7DTlWPgX6zs - NathanOliver
2
简而言之,使用vector{...}从列表(包括0个元素)初始化,使用vector(...)调用所有其他构造函数。 “通用”并不意味着“这是替代品”。它只是意味着您现在可以在所有对象上进行列表初始化,而不仅仅是其中一些。 - Mooing Duck
显示剩余8条评论
2个回答

17
短回答:你不能
这不是关于统一初始化的问题,而是与std::initializer_list有关。按照overload resolution特殊规则,如果使用list-initialization,则始终优先考虑接受std::initializer_list参数的构造函数,而不管是否存在需要更少的隐式转换的其他构造函数。
我建议使用
std::vector<unsigned char> buffer(bufferSize, ' ');

或者,如果您确实想使用列表初始化,请创建一个围绕std::vector的封装器,提供构造函数重载以执行正确操作。


7

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时,重载决议会首选 initializer-list 构造函数。

list-initialization 不允许缩小转换,你尝试创建一个 T=unsigned charstd::vector,但是对于 std::initializer_list 参数推导出的 TT=unsigned long,这将涉及到缩小转换(不允许)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接