I have a (third-party) class which is non-copyable. I'd like to initialize an array of them. Here's my best attempt:
#include <array>
class Thing
{
public:
explicit Thing(int) {}
Thing(const Thing&) = delete;
};
int main()
{
std::array<Thing, 1> things{{{100}}}; // error here
};
GCC 4.7.2 says:
error: converting to ‘std::array::value_type {aka Thing}’ from initializer list would use explicit constructor ‘Thing::Thing(int)’
OK, but that's exactly what I want--to use the explicit constructor. How can I express that? If I actually invoke the constructor myself, then I get an error about the copy constructor being deleted. And I can't use std::move()
because Thing is not movable (and I can't modify it).
The only alternative I've found so far is https://stackoverflow.com/a/15962814/4323 but this is undesirable because it's a bunch of extra code plus I need to cast the "storage" everywhere I use it (or keep a separate pointer to it, which adds indirection I don't want).
I want a solution that gives maximum performance when actually using the Things without a lot of ugly boilerplate.
Yet again, C++17's guaranteed copy elision comes to the rescue: an expression like Thing{100}
no longer creates an object but merely specifies how some other object (your array element) is to be created.