I have a std::map
I'm trying to initialize with an initialization list. I do this in two places, in two different ways. The first one works, while the other one causes the error mentioned in the title.
Here's the one that works:
void foo() {
static std::map<std::string, std::string> fooMap =
{
{ "First", "ABC" },
{ "Second", "DEF" }
};
}
While this one does not:
class Bar {
public:
Bar();
private:
std::map<std::string, std::string> barMap;
};
Bar::Bar() {
barMap = { // <-- this is the error line
{ "First", "ABC" },
{ "Second", "DEF" }
};
}
Why do I get the error when trying to initialize the class member, while the static map works? At the moment, I can populate the member by first creating a local variable and then swapping it with the member like this:
Bar::Bar() {
std::map<std::string, std::string> tmpMap = {
{ "First", "ABC" },
{ "Second", "DEF" }
};
barMap.swap(tmpMap);
}
However, this feels rather counter-intuitive compared to just populating the member directly.
EDIT: Here's the compiler output.
This is a bug in your compilers overload resolution mechanism - or its standard library implementation. Overload resolution clearly states in [over.ics.rank]/3 that
— List-initialization sequence
L1
is a better conversion sequence than list-initialization sequenceL2
ifL1
converts tostd::initializer_list<X>
for someX
andL2
does not.
Here, X
is std::pair<std::string, std::string>
. L1
converts your list to the parameter of
map& operator=( std::initializer_list<value_type> ilist );
Whilst L2
converts the list to one of the following functions' parameters:
map& operator=( map&& other );
map& operator=( const map& other );
Which clearly aren't initializer_list
s.
barMap = decltype(barMap){
{ "First", "ABC" },
{ "Second", "DEF" }
};
Which should select the move-assignment operator (Demo with VC++). The temporary should also be optimized away according to copy elision.
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