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