简体   繁体   English

如何在没有指针的情况下正确地将 class 对象插入 map?

[英]How to insert class objects to map correctly without pointers?

this is my code:这是我的代码:

LoggedUser.h登录用户.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房间.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房间管理器.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房间管理器.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"问题出在 function createRoom 中的文件 RoomManager.cpp 中,我正在尝试将他的 ID 插入到地图<unsigned int, Room> 中,但我收到此错误“C2512 'Room::Room': no适当的默认构造函数可用"

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.现在,我知道我可以通过插入 Room 的指针而不是 object 本身来解决这个问题,但我想知道是否有办法在没有指针的情况下做到这一点,这样我就知道我的代码中出了什么问题。 Thanks for everyone who helping.感谢所有帮助的人。

In the m_rooms[roomData.id] = Room(roomData, loggedUser);m_rooms[roomData.id] = Room(roomData, loggedUser); statement you use the std::map::operator[] , which...声明您使用std::map::operator[] ,其中...

...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.因此,只有在mapped_type具有默认构造函数时,我们才可以使用运算符。 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.由于要在map中插入一个“后备”值(如果我们访问一个尚不存在的键),因此需要在运行中默认构造一个。

But since you did provide non-default constructors for Room , the compiler does not synthesizes the default one for you.但是由于您确实为Room提供了非默认构造函数,因此编译器不会为您合成默认构造函数。 Thus, the Room is not DefaultInsertable.因此, Room不是 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 .经验教训: std::map::operator[]要求mapped_typeDefaultInsertable For more, refer to the documentation .有关更多信息,请参阅 文档

You are using operator[] to insert an item into the std::map .您正在使用operator[]将项目插入std::map This operation requires that the inserted item is DefaultConstructible 1 .此操作要求插入的项目是DefaultConstructible 1

The Room class is not DefaultConstructibel , as explained in the other answer by @rawrex.正如@rawrex 在另一个答案中所解释的那样, Room class 不是DefaultConstructibel

If you cannot or do not want to add a default constructor, you can also use the insert() function to insert an item.如果您不能或不想添加默认构造函数,也可以使用insert() function 来插入项目。 This function does not have the above requirement.此 function 没有上述要求。

m_rooms.insert(std::make_pair(roomData.id, Room(roomData, loggedUser)));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM