I came across this while testing some stuff for another question on initializing aggregates. I'm using GCC 4.6.
When I initialize an aggregate with a list, all the members are constructed in place, without copying or moving. To wit:
int main()
{
std::array<std::array<Goo,2>,2>
a { std::array<Goo,2>{Goo{ 1, 2}, Goo{ 3, 4}} ,
std::array<Goo,2>{Goo{-1,-2}, Goo{-3,-4}} };
}
Let us confirm by making some noisy constructors:
struct Goo
{
Goo(int, int) { }
Goo(Goo &&) { std::cout << "Goo Moved." << std::endl; }
Goo(const Goo &) { std::cout << "Goo Copied." << std::endl; }
};
Upon running, no messages are printed. However, if I make the move constructor private, the compiler complains with ‘Goo::Goo(Goo&&)’ is private
, although the move constructor is patently not needed.
Does anyone know if there's a standard requirement for the move constructor to be accessible for aggregate initialization like this?
Not calling the copy or move constructor is an optimization specifically allowed by the standard (but not required).
To be consistent across compilers, an implementation must check that the constructor could have been called, if it didn't care to optimize it out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With