向量

时间:2015-07-23 17:52:07

标签: c++11 vector

我遇到了this一篇文章,其中我在其中一张海报中读到了这个例子。为方便起见,我在这里引用了这一点。

struct Foo
{
    Foo(int i) {} // #1
    Foo() {}
};

int main()
{
    std::vector<Foo> f {10};

    std::cout << f.size() << std::endl;
}
  

如上所述,上面的代码发出“1”(10是由a转换为Foo   获取int的构造函数,然后是vector的initializer_list   构造函数被调用)。如果我注释掉被评为#1的行,那么   结果是“10”(初始化器列表无法转换为int   使用了构造函数)。

我的问题是,如果删除了int构造函数,为什么它会发出10。 我知道统一初始化列表按以下顺序工作

1-Calls the initializer list if available or possible
2-Calls the default constructor if available
3-Does aggregate initialization

在上面的例子中,为什么在向量中创建10个项目,因为1,2和3是不可能的?这是否意味着统一初始化项目的向量可能总是有不同的行为?

1 个答案:

答案 0 :(得分:3)

借用Scott Meyers在Effective Modern C ++中的引用(强调原文):

  

但是,如果一个或多个构造函数声明类型为std::initializer_list的参数,则使用支撑初始化语法的调用非常喜欢使用std;:initializer_list s的重载。 强烈。如果以任何方式让编译器将使用支撑初始值设定项的调用解释为采用std::initializer_list的构造函数,编译器将采用该解释。

因此,当您拥有std::vector<Foo> f {10};时,它会尝试使用vector<Foo>的{​​{1}}构造函数。如果initializer_list<Foo>可以从Foo构建,那就是我们正在使用的构造函数 - 所以我们最终得到一个int构建的Foo

或者,从标准,[over.match.list]:

  

当非聚合类类型10的对象被列表初始化(8.5.4)时,重载决策选择构造函数   分两个阶段:

     

(1.1) - 最初,候选函数是类T的初始化列表构造函数(8.5.4)和   参数列表由初始化列表作为单个参数组成   (1.2) - 如果找不到可行的初始化列表构造函数,则再次执行重载解析,其中   候选函数是类T的所有构造函数,参数列表由元素组成   初始化列表。

如果一个可行的初始化列表构造函数,则使用它。如果你没有T构造函数,那么就没有可行的初始化列表构造函数,并且第二次重载解析会找到Foo(int )的构造函数需要一个大小 - 所以你'得到一个10个默认构造的vector的向量。