Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 array initialization with a non-copyable type with explicit constructor

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.

like image 344
John Zwinck Avatar asked Apr 08 '14 03:04

John Zwinck


1 Answers

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.

like image 191
Davis Herring Avatar answered Sep 28 '22 06:09

Davis Herring