Map to user-defined class

I have created a map between std::strings and a class I wrote called 'Room'. Right now room doesn't do anything, but the constructor takes four strings.

When I try to create a key-data pair;

1
2
std::map<std::string,Room> rooms;
rooms["Starting Room"]=Room("nowhere","nowhere","nowhere","nowhere");


I get;
error: no matching function for call to 'Room::Room()'
note: candidates are:
note: Room::Room(std::string, std::string, std::string, std::string)
note:   candidate expects 4 arguments, 0 provided
note: Room::Room(const Room&)|
note:   candidate expects 1 argument, 0 provided|
||=== Build failed: 1 error(s), 2 warning(s) (0 minute(s), 1 second(s)) ===|


In stl_map.h
Last edited on
rooms.emplace("Starting Room", {"nowhere", "nowhere", "nowhere", "nowhere"});

Make sure to compile as C++11/C++14
Last edited on
error: no matching function for call to 'std::map<std::basic_string<char>, Room>::emplace(const char [14], <brace-enclosed initializer list>)'|
note: candidate is: std::pair...
stl_map.h|540|note:   candidate expects 0 arguments, 2 provided

g++ 4.8.1, -std=c++11
Last edited on
1
2
// rooms.emplace("Starting Room", {"nowhere", "nowhere", "nowhere", "nowhere"});
rooms.emplace( "Starting Room", Room{ "nowhere", "nowhere", "nowhere", "nowhere" } );

A braced-init-list is not an expression; template type deduction cannot deduce a type that matches a braced-init-list.
http://en.cppreference.com/w/cpp/language/overload_resolution#Implicit_conversion_sequence_in_list-initialization


Consider making Room DefaultConstructible
(For all operations of std::map<> to be available - for instance operator[] - the mapped_type must be DefaultConstructible.)
@LB: actually correct way is to do that:
1
2
3
rooms.emplace(std::piecewise_construct,
              std::forward_as_tuple("Starting Room"),
              std::forward_as_tuple("nowhere", "nowhere", "nowhere", "nowhere"));


But making contained type DefaultConstructible is something to consider. Otherwise you will have to use your map really carefully.
Last edited on
> actually correct way is to do that:
>
1
2
3
rooms.emplace(std::piecewise_construct,
              std::forward_as_tuple("Starting Room"),
              std::forward_as_tuple("nowhere", "nowhere", "nowhere", "nowhere"));


Strongly favour rooms.emplace( "Starting Room", Room{ "nowhere", "nowhere", "nowhere", "nowhere" } );
if Room is MoveConstructible. IMHO.
Topic archived. No new replies allowed.