【问题标题】:Uniform initialization behavior different for different types in vector向量中不同类型的统一初始化行为不同
【发布时间】:2015-07-23 17:52:06
【问题描述】:

我遇到了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,然后是向量的 initializer_list 构造函数被调用)。如果我注释掉注释为 #1 的行,则 结果是“10”(initializer_list 无法转换,因此 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 是不可能的?这是否意味着通过统一初始化,项目向量可能总是具有不同的行为?

【问题讨论】:

  • 您的术语似乎不对。默认 c'tor 是可以在没有参数的情况下调用的那个(如果有多个这样的 c'tor,由于默认参数,那么使用它的尝试将是模棱两可的)。不能在这里调用它,因为这需要空的或没有括号/大括号。聚合初始化仅适用于没有构造函数的 POD,不适用于 std::vector(例如用于 std::array 和其他 C 样式结构)。如果您将 2. 更改为“调用具有兼容参数类型的构造函数”,它会更有意义,但聚合 init.和 c'tors 真的是非此即彼。
  • 澄清一下(我用完了字符):聚合初始化绝不是调用某些构造函数的后备。仅当类或结构根本没有构造函数时才可用。因此,如果一个类有一个构造函数,但既不能调用带有 std::initializer_list 的构造函数,也不能调用具有兼容参数的构造函数,则不会回退到聚合初始化。相反,程序格式错误。
  • @ArneVogel 答案属于答案 - 不要写多段 cmets...

标签: c++11 vector


【解决方案1】:

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

但是,如果一个或多个构造函数声明了std::initializer_list 类型的参数,则使用大括号初始化语法的调用强烈倾向于采用std;:initializer_lists 的重载。 强烈。如果编译器有任何方式将使用大括号初始化程序的调用解释为采用std::initializer_list 的构造函数,编译器将采用该解释。

所以当你有std::vector&lt;Foo&gt; f {10}; 时,它会尝试使用vector&lt;Foo&gt; 的构造函数,它接受initializer_list&lt;Foo&gt;。如果Foo 可以从int 构造,那就是我们正在使用的构造函数——所以我们最终会得到一个从10 构造的Foo

或者,从标准的角度来看,在 [over.match.list] 中:

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

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

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

【讨论】:

    猜你喜欢
    • 2017-05-05
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-07
    相关资源
    最近更新 更多