为啥 std::mutex 在带有 WIndows SOCKET 的结构中使用时会创建 C2248?

Posted

技术标签:

【中文标题】为啥 std::mutex 在带有 WIndows SOCKET 的结构中使用时会创建 C2248?【英文标题】:Why does std::mutex create a C2248 when used in a struct with WIndows SOCKET?为什么 std::mutex 在带有 WIndows SOCKET 的结构中使用时会创建 C2248? 【发布时间】:2013-01-10 17:33:02 【问题描述】:

我正在使用一个结构来支持 Windows SOCKET 的列表:

struct ConnectedSockets
    std::mutex lock;
    std::list<SOCKET> sockets;
;

当我尝试编译这个 (Visual Studio 2012) 时,我收到以下错误:

“错误 C2248:std::mutex::operator = 无法访问在类 'std::mutex' 中声明的 'private' 成员”

有人知道如何解决这个问题吗?

【问题讨论】:

附带说明,类的std::mutex 成员几乎总是mutable 【参考方案1】:

std::mutex 不可复制,因此您需要自己为ConnectedScokets 实现operator=

我想你想为ConnectedSockets 的每个实例保留一个mutex,所以这就足够了:

ConnectedSockets& operator =( ConnectedSockets const& other )

    // keep my own mutex
    sockets = other.sockets; // maybe sync this?

    return *this;

【讨论】:

谢谢 :) 这个做的工作。【参考方案2】:

根本原因与套接字无关。 std::mutex 不可复制,因此编译器无法为 ConnectedSockets 结构生成默认赋值运算符(按成员)。您需要指示编译器删除赋值运算符(使用= delete 说明符声明它)或手动实现它,例如忽略互斥复制。

// To make ConnectedSockets explicitly non-copyable and get more reasonable
// compiler error in case of misuse
struct ConnectedSockets

   std::mutex lock; 
   std::list<SOCKET> sockets;
   ConnectedSockets& operator=(const ConnectedSockets&) = delete;
;

// To make ConnectedSockets copyable but keep mutex member intact
struct ConnectedSockets

   std::mutex lock; 
   std::list<SOCKET> sockets;

   ConnectedSockets& operator=(const ConnectedSockets& i_rhs)
   
      // Need locking? Looks like it can be problem here because
      // mutex:lock() is not const and locking i_rhs wouldn't be so easy
      sockets = i_rhs.sockets;
      return *this;
   
;

【讨论】:

以上是关于为啥 std::mutex 在带有 WIndows SOCKET 的结构中使用时会创建 C2248?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C++ 中 std::mutex 的构造函数不抛出?

为啥将 std::mutex 引入成员类会产生此编译错误?

为啥使用 std::mutex 的函数对 pthread_key_create 的地址进行空检查?

带有 RAII 的 std::mutex 但在后台线程中完成和释放

使用 MXE gcc 构建 Qt 应用程序时缺少 std::mutex

std::mutex 锁定函数和 std::lock_guard<std::mutex> 的区别?