C++ 在C+中,聚合初始化何时有效+;11?

C++ 在C+中,聚合初始化何时有效+;11?,c++,optimization,c++11,aggregate,aggregate-initialization,C++,Optimization,C++11,Aggregate,Aggregate Initialization,假设我们有以下代码: #include <iostream> #include <string> struct A { A() {} A(const A&) { std::cout << "Copy" << std::endl; } A(A&&) { std::cout << "Move" << std::endl; } std::string s; }; struct B {

假设我们有以下代码:

#include <iostream>
#include <string>

struct A
{
  A() {}
  A(const A&) { std::cout << "Copy" << std::endl; }
  A(A&&) { std::cout << "Move" << std::endl; }
  std::string s;
};

struct B
{
  A a;
};

int main()
{
  B{A()};
}
执行移动

因此,如果这只是一个统一的初始化,只是调用构造函数,而不做任何特殊的事情,那么我该如何编写一个允许省略移动的构造函数呢


或者GCC只是在有效的情况下没有在这里省略移动,如果是这样,是否有编译器和优化设置可以省略移动?

这根本不是聚合初始化,而是统一初始化,在这种情况下基本上意味着调用构造函数,无复制或移动可能由RVO和NRVO完成。

根据新标准第8.5.1条(聚合),一个足够简单的类型(例如,没有用户定义的构造函数)可以作为聚合。对于这样的聚合
Foo
,写入
foox{a,b,…}将从列表项构造成员

简单的例子:

struct A
{
  std::unordered_map<int, int> a;
  std::string b;
  std::array<int,4> c;
  MyClass d; // Only constructor is MyClass(int, int)
};

// Usage:
 A x{{{1,-1}, {12, -2}}, "meow", {1,2,3,4}, MyClass(4,4)};
// Alternative:
 A x{{{1,-1}, {12, -2}}, "meow", {1,2,3,4}, {4,4}};
结构A { std::无序地图a; std::字符串b; std::数组c; MyClass d;//唯一的构造函数是MyClass(int,int) }; //用法: A x{{{1,-1},{12,-2},{1,2,3,4},MyClass(4,4)}; //备选方案: A x{{{1,-1},{12,-2},{1,2,3,4},{4,4};

对象
x
构造时,所有相关的构造函数都已执行到位。没有地图、字符串或MyClass被复制或移动。请注意,底部的两个变体执行相同的操作。如果愿意,您甚至可以将MyClass的复制和移动构造函数设置为私有的。

您所说的“省略移动”是什么意思?移动建筑已经是一个非常便宜的操作,如果做得好,你为什么要省去它?在您的示例中,您可以为
B
编写一个构造函数,该构造函数接受
a
的相关参数,这样您就可以在B的初始值设定项列表中构造
B::a
,但您到底关心什么?问得好。有兴趣看看结果如何。@Kerrek SB:如何使std::array的移动构造更便宜?@Clinton:通过有效地使用RVO和NRVO。@Clinton:
std::array
是一种简单的聚合类型,没有自定义构造函数。因此,它的所有构造函数都是自动生成的,一个简单的
数组newarray(move(oldarray))
应该做正确的事情(如果你不确定的话,自己检查程序集)。@Clinton:web编译器的优化功能可能非常有限,你只是把它弄糊涂了。你说的“统一初始化”是什么意思?FDIS中使用了这个术语吗?这个术语已经存在一段时间了。这意味着您可以使用相同的语法,
foox{a,b,c},在各种情况下:初始化数组、聚合或调用特定的用户定义构造函数。实际上,FDI中并没有“统一初始化”这一措辞,但如果您阅读初始化部分(8.5),您会发现所有初始化需求都可以通过某种形式的花括号来满足。
struct A
{
  std::unordered_map<int, int> a;
  std::string b;
  std::array<int,4> c;
  MyClass d; // Only constructor is MyClass(int, int)
};

// Usage:
 A x{{{1,-1}, {12, -2}}, "meow", {1,2,3,4}, MyClass(4,4)};
// Alternative:
 A x{{{1,-1}, {12, -2}}, "meow", {1,2,3,4}, {4,4}};