I have a map defined as:
std::map<unsigned int, std::string> spCalls;
I also have a function that returns the string, given the key. It is defined as:
std::string spGetCallString(unsigned int key)
{
auto iter{ spCalls.find(key) };
return iter->second;
}
When attempting to compile this, with GCC, I get an error which says
error: base operand of '->' has non-pointer type
'std::initializer_list < std::_Rb_tree_iterator < std::pair < const unsigned int, std::basic_string < char> > > >'
return iter->second;"
I just cannot make any sense of this and I can't see why my code shouldn't work. I appreciate any help.
Before C++17, auto type deduction for braced initializer will always yield type of instantiation of std::initializer_list
, so for auto iter{ spCalls.find(key) };
, the type of iter
would be std::initializer_list<std::map<unsigned int, std::string>::iterator>
, which doesn't match the usage at all.
Since C++17 you'll get the correct type for it, i.e. std::map<unsigned int, std::string>::iterator
.
In direct-list-initialization (but not in copy-list-initalization), when deducing the meaning of the auto from a braced-init-list, the braced-init-list must contain only one element, and the type of auto will be the type of that element:
auto x1 = {3}; // x1 is std::initializer_list<int> auto x2{1, 2}; // error: not a single element auto x3{3}; // x3 is int (before C++17 it was std::initializer_list<int>)
If your compiler still doesn't support that, you could change braced initializer to other initializers, e.g.
auto iter = spCalls.find(key);
auto iter(spCalls.find(key));