c++ - 大括号初始化列表中的对象创建顺序

标签 c++ visual-studio c++11 visual-studio-2013

#include <iostream>

struct A
{
    A() { std::cout << "(A::A)"; }
};

struct B
{
    B() { std::cout << "(B::B)"; }
};

struct C
{
    template<typename ...Args>
    C(Args && ...) {}
};

int main(int agrc, char *argv[])
{
    C {A(), B()}; // <-- prints (B::B)(A::A)
    std::cout << std::endl;
    C {(A(), B())}; // <-- prints (A::A)(B::B)
    std::cout << std::endl;

    return 0;
}

我有 2 个问题:

  • 为什么在第一个大括号初始化列表中对象是按从右到左的顺序创建的?
  • 为什么第二种情况下的括号会恢复此顺序?

编辑:我已经用 msvs 2013 编译了它

最佳答案

在第二种情况下,您实际上只是使用 B(); 进行初始化;通过逗号操作符的使用,A()首先被构造和丢弃。

C {(A(), B())};
//|^^^^^^^^^^|
//      \--------> (A(), B())
//                  ^^^  ^^^
//                   |    |
//                   /    \
//            evaluated,   THEN evaluated,
//            discarded      used

另一方面,在第一个实例中,您通过初始化列表从 both 临时变量中初始化 C,其元素也应该从左到右进行评估- 对,碰巧,但你的编译器在这方面有问题:

[C++11: 8.5.4/4]: Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack expansions (14.5.3), are evaluated in the order in which they appear. That is, every value computation and side effect associated with a given initializer-clause is sequenced before every value computation and side effect associated with any initializer-clause that follows it in the comma-separated list of the initializer-list. [ Note: This evaluation ordering holds regardless of the semantics of the initialization; for example, it applies when the elements of the initializer-list are interpreted as arguments of a constructor call, even though ordinarily there are no sequencing constraints on the arguments of a call. —end note ]

我可以使用 GCC 4.8* 重现该问题,但 Clang 3.5 的行为正常std-discussion 列表中已经讨论过该错误,但我还没有找到 GCC Bugzilla ID§。 p>

C {A(), B()};
// ^^^  ^^^
//  |    \
// eval-  THEN
// uated   evaluated
//  \       /
//   \     /
//  both used

* http://coliru.stacked-crooked.com/a/1f18e0d1f8973f3c
http://coliru.stacked-crooked.com/a/5a6e7506e9be97c3
https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/TQUnBFkUBDg
§ #51253可能是相关的。

关于c++ - 大括号初始化列表中的对象创建顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21234380/

相关文章:

c++ - boost 属性树 : how to store pointers in it?

c++ - 从 MFC C++ 6.0 应用程序迁移到 VS 2005

asp.net - 如何让 JavaScript/jQuery Intellisense 在 Visual Studio 2008 中工作?

c++ - 在 ASIO 中对 UDP 调用 receive_from 应用超时

c++ - 字符指针数组

c++ - 正确增加指针?

c++ - 工作目录 - 解决方案

visual-studio - VS2017 RC - 尝试配置 IIS Express 时出现以下错误

c++ - 如何修复 "array rvalue"无法使用 gcc-4.8 和 clang-3.7 进行编译的问题?

c++ - 将函数分配给 std::function 类型时调用哪个函数原型(prototype)(以及如何调用)?