I have the following code which won't compile and it's Friday and I'm a bit frazzled.
#include <string>
#include <memory>
#include <utility>
#include <map>
template< typename T, typename ...Args >
std::unique_ptr< T > make_unique( Args && ...args )
{
return std::unique_ptr< T >( new T( std::forward< Args >( args )... ) );
}
struct A
{
};
std::map< std::string, std::unique_ptr< A > > _map = { { "A", make_unique< A >() } }; // <-- ERROR!!
The following compiles without a problem
int main()
{
std::pair< std::string, std::unique_ptr< A > > p { "B", make_unique< A >() };
_map.insert( std::make_pair( "C", make_unique< A >() ) );
}
The error I'm getting is (roughly, as removed g++ fluff)
use of deleted function 'constexpr std::pair<...>( const st::pair<...> & )
'constexp std::pair<...>::pair( const std::pair<...> & ) is implicitly deleted because the default definition would be illegal.
Argghh!! Just read this in the c++11 standard.
When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause
bummer!!!
Anyone know if it's just plain impossible with initialiser lists?
You can't do much about it: elements in an initializer list are copied. This will not get along with classes that are move-only.
There's a way to bypass this "defect" but it isn't very nice to read; you decide
using map_type = std::map< std::string, std::unique_ptr< A > >;
using pair_type = map_type::value_type;
pair_type elements[] = { { "A", std::make_unique< A >() }, { "B", std::make_unique< A >() } };
map_type myMap { std::make_move_iterator( begin(elements) ), std::make_move_iterator( end(elements) ) };
which will make myMap
iterate over the range and move the elements within, rather than copying. Method kindly taken from this other question.
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