首页 > 解决方案 > 尝试将套接字存储到结构中时出现问题

问题描述

我正在尝试将套接字存储到结构中。我认为这将是直截了当的,但套接字没有构造函数(据我所知)这一事实使这件事对我来说非常棘手。这是我尝试过的:

    struct participants_name {
      participants_name(tcp::socket);
      chat_participant_ptr _participant;
      std::string name;
      std::string password;
      bool logged_in;
      tcp::socket socket_;
      std::map<std::string, contacts_> contacts;
    };


participants_name::participants_name(tcp::socket socket): socket_(std::move(socket))
{

}

void chat_session::add_participants(chat_participant_ptr chat_participant)
{
  this->participants[chat_participant] = participants_name(std::move(socket_));
  this->participants[chat_participant]._participant = chat_participant;
  this->participants[chat_participant].logged_in = false;

  std::cout << "Participant "<< chat_participant << " has connected\n";
}

这是会话的样子:

class chat_session : public chat_participant,
    public std::enable_shared_from_this<chat_session>
{
  public:
       
    chat_session::chat_session(tcp::socket socket, chat_room& room,
      std::map<chat_participant_ptr, participants_name> 
      &participants_):
      socket_(std::move(socket)), room_(room), 
      participants(participants_)
    {
      commands["LOGIN"] = &chat_session::login;
      commands["ADDCONTACT"] = &chat_session::add_friend;
    }

    void start();
    void chat_session::add_participants(chat_participant_ptr chat_participant)


    [...... A few methods here ..... ]


    typedef void (chat_session::*cmdfunctions)(std::string, chat_participant_ptr);
    typedef std::map<std::string, cmdfunctions> functions_map;

    functions_map commands;
    tcp::socket socket_;
    chat_room room_;
    std::map<chat_participant_ptr, participants_name> &participants;
    chat_message read_msg_;
    chat_message_queue write_msgs_;
};

class chat_server
{
public:
  chat_server(boost::asio::io_service& io_service,
      const tcp::endpoint& endpoint)
    : acceptor_(io_service, endpoint),
      socket_(io_service) { do_accept(); }

private:
  void do_accept();
  tcp::acceptor acceptor_;
  tcp::socket socket_;
  chat_room room_;
  std::map<chat_participant_ptr, participants_name> participants;

};

以下是编译器抱怨的内容: [...] /usr/include/c++/10.2.0/tuple:1689:70: error: no matching function for call to 'participants_name::participants_name()' 1689 | 第二(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)

我已经尝试了很多东西,但没有任何效果,任何帮助将不胜感激!

标签: c++socketsboost-asio

解决方案


The error is caused here

  this->participants[chat_participant] = participants_name(std::move(socket_));

not because the participants_name object on the right side of the assignment couldn't be constructed, but because the new entry in the map

std::map<chat_participant_ptr, participants_name> &participants;

can't be created, because struct participants_name doesn't have a default constructor (with no arguments).

That's because in the way it's written, map[key] = value, the map will have to

  • first enter a new pair of (key, default value)
  • return a reference to the newly created default value
  • assign the new value over it.

You can avoid the error by constructing the new map entry in-place, in this way:

  this->participants.emplace(chat_participant, participants_name(std::move(socket_)));

推荐阅读