Допустим, у нас есть следующий код:
#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()};
}
Здесь я считаю, что struct A
не является совокупностью, поскольку она имеет как нетривиальные конструкторы, так и член std::string
, который, как я полагаю, не является совокупностью. Это предположительно означает, что B
также не является совокупностью.
Тем не менее, я могу агрегировать инициализацию B. Кроме того, это можно сделать без вызова вызываемого экземпляра или перемещения конструктора (например, С++ 0x GCC 4.5.1 на ideone).
Такое поведение кажется полезной оптимизацией, особенно для компоновки больших типов стеков, которые не имеют дешевых ходов.
Мой вопрос: когда этот тип инициализации агрегата действителен в С++ 0x?
Изменить + следующий вопрос:
DeadMG ниже ответил следующим:
Это не сводная инициализация вообще, это равномерная инициализация, которая в основном в этом случае означает вызов конструктора, а no copy или move, вероятно, выполняются RVO и NRVO.
Обратите внимание, что когда я меняю B
на следующее:
struct B
{
A a;
B(const A& a_) : a(a_) {}
B(A&& a_) : a(std::move(a_)) {}
};
Выполняется перемещение.
Итак, если это просто равномерная инициализация и просто вызов конструктора и ничего особенного не делает, то как я могу написать конструктор, который позволяет двигаться в сторону?
Или GCC просто не ускоряет движение здесь, когда это действительно так, и если да, существует ли параметр компилятора и оптимизации, который будет преодолевать ход?