gpt4 book ai didi

c++ - 用双花括号初始化 vector :std::string vs int

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:50:35 25 4
gpt4 key购买 nike

在这个问题的回答中:Initializing vector<string> with double curly braces

表明

vector<string> v = {{"a", "b"}};

将调用带有 initializer_liststd::vector 构造函数和一个元素。因此 vector 中的第一个(也是唯一一个)元素将从 {"a", "b"} 构造。这会导致未定义的行为,但这超出了这里的重点。

我发现的是

std::vector<int> v = {{2, 3}};

将使用两个元素initializer_list调用std::vector构造函数。

造成这种行为差异的原因是什么?

最佳答案

类类型列表初始化的规则基本上是:首先,只考虑std::initializer_list做重载决策。构造函数,然后,如有必要,对所有构造函数进行重载解析(这是 [over.match.list] )。

初始化 std::initializer_list<E> 时从初始化列表中,就好像我们具体化了一个 const E[N]来自初始化列表中的 N 个元素(来自 [dcl.init.list]/5 )。

对于 vector<string> v = {{"a", "b"}};我们先试试initializer_list<string>构造函数,这将涉及尝试初始化一个数组 1 const string , 与一个string{"a", "b"} 初始化.由于 string 的迭代器对构造函数,这是可行的 ,所以我们最终得到一个包含一个字符串的 vector (这是 UB,因为我们违反了该字符串构造函数的先决条件)。这是简单的情况。


对于 vector<int> v = {{2, 3}};我们先试试initializer_list<int>构造函数,这将涉及尝试初始化一个数组 1 const int , 与一个int{2, 3} 初始化.这不可行

那么,考虑到所有 vector 重做重载决议构造函数。现在,我们得到了两个可行的构造函数:

  • vector(vector&& ) ,因为当我们在那里递归初始化参数时,初始化列表将是 {2, 3} - 我们将尝试用它来初始化 2 const int 的数组,这是可行的。
  • vector(std::initializer_list<int> ) , 再次。这次不是来自正常的列表初始化世界,而是直接初始化 initializer_list来自同一个{2, 3}初始化列表,出于同样的原因,它是可行的。

要选择哪个构造函数,我们必须进入 [over.ics.list] , 其中vector(vector&& )构造函数是 user-defined conversion sequence但是 vector(initializer_list<int> )构造函数是 identity ,所以首选。


为了完整性,vector(vector const&)也是可行的,但出于其他原因,我们更喜欢移动构造函数而不是复制构造函数。

关于c++ - 用双花括号初始化 vector :std::string vs int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46665914/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com