this is my code:
LoggedUser.h
#pragma once
#include <string>
using std::string;
class LoggedUser {
private:
string m_username;
public:
LoggedUser(string username);
string getUsername() const;
bool operator==(LoggedUser loggedUser) const;
};
Room.h
#pragma once
#include <LoggedUser.h>
#include <string>
#include <vector>
using std::vector;
using std::string;
typedef struct RoomData {
unsigned int id = 0;
string name;
unsigned int maxPlayers = 4;
const unsigned int timePerPlay = 10;
bool isActive = false;
RoomData& operator=(const RoomData& roomData) {
this->id = roomData.id;
this->isActive = roomData.isActive;
this->maxPlayers = roomData.maxPlayers;
this->name = roomData.name;
return *this;
}
} RoomData;
class Room {
private:
RoomData m_metadata;
vector<LoggedUser> m_users;
public:
Room(const Room& room);
Room(RoomData roomData, LoggedUser loggedUser);
int getUserIndex(const LoggedUser& loggedUser);
void addUser(LoggedUser loggedUser);
void removeUser(LoggedUser loggedUser);
vector<LoggedUser> getAllUsers();
unsigned int getId();
string getName();
unsigned int getMaxPlayers();
bool getIsActive();
};
RoomManager.h
#pragma once
#include <map>
#include "Room.h"
class RoomManager {
private:
std::map<unsigned int, Room> m_rooms;
public:
void createRoom(LoggedUser loggedUser, RoomData roomData);
}
RoomManager.cpp
#include "RoomManager.h"
void RoomManager::createRoom(LoggedUser loggedUser, RoomData roomData)
{
m_rooms[roomData.id] = Room(roomData, loggedUser);
}
The problem is in the file RoomManager.cpp in the function createRoom i'm trying to insert to the map<unsigned int, Room>, a room by his id, but i get this error "C2512 'Room::Room': no appropriate default constructor available"
now, i know i can fix this by inserting a pointer of Room instead of the object itself, but i want to know if there is a way to do it without pointers, just so i know what was the problem in my code. Thanks for everyone who helping.
In the m_rooms[roomData.id] = Room(roomData, loggedUser);
statement you use the std::map::operator[]
, which...
...returns a reference to the value that is mapped to a key equivalent to (requested) key, performing an insertion if such key does not already exist .
Thus, we may use the operator only if the mapped_type
has a default constructor. Since to insert a "fallback" a value into the map
(if we access a key that is not in there yet) it will need to default construct one on the fly.
But since you did provide non-default constructors for Room
, the compiler does not synthesizes the default one for you. Thus, the Room
is not DefaultInsertable.
So we can handle this by simply introducing a defaulted default constructor :
class Room {
// Other private members as before
public:
// Other public members as before
Room() = default;
};
Lesson learned: std::map::operator[]
require mapped_type
to be DefaultInsertable . For more, refer to the documentation .
You are using operator[]
to insert an item into the std::map
. This operation requires that the inserted item is DefaultConstructible 1 .
The Room
class is not DefaultConstructibel , as explained in the other answer by @rawrex.
If you cannot or do not want to add a default constructor, you can also use the insert()
function to insert an item. This function does not have the above requirement.
m_rooms.insert(std::make_pair(roomData.id, Room(roomData, loggedUser)));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.