声明为私有成员的 Mutex 会产生错误,但当它是全局成员时不会

Mutex declared as private member generates an error but not when it is global

当我尝试将 std::mutex mtx 放入对象时,为什么会出现错误?当它被声明为全局时,没有错误。我的语法有问题吗?

错误说:

std::tuple<void (__thiscall XHuman::* )(int),XHuman,int>::tuple(std::tuple<void (__thiscall XHuman::* )(int),XHuman,int> &&)': cannot convert argument 1 from 'void (__thiscall XHuman::* )(int)' to 'std::allocator_arg_t

std::tuple<void (__thiscall XHuman::* )(int,int),XHuman,int,int>::tuple': no overloaded function takes 4 arguments

这是我的代码

#include "stdafx.h"
#include <vector>
#include <Windows.h>
#include <thread>
#include <mutex>


class XHuman
{
private:
    std::vector<int> m_coordinates;
    std::mutex mtx;

public:
    XHuman() {
        printf("Initialized XHuman\n");
        for (int i = 0; i < 5; ++i){
            m_coordinates.push_back(i);
        }
    }
    std::vector<int> Coordinates() { return m_coordinates; }
    void operator()() {
        printf("hello\n");
    }

    void addValues(int val, int multiple)
    {
        std::lock_guard<std::mutex> guard(mtx);
        for (int i = 0; i < multiple; ++i){
            m_coordinates.push_back(val);
            printf("pushed_back %d\n", val);
            Sleep(100);
        }
        printf("m_coordinates.size() = %d\n", m_coordinates.size());
    }

    void eraseValues(int multiple)
    {
        std::lock_guard<std::mutex> guard(mtx);
        for (int i = 0; i < multiple; ++i) {
            m_coordinates.pop_back();
            printf("m_coordinates.size() = %d\n", m_coordinates.size());
        }
    }
};

int main()
{
    std::thread th1(&XHuman::addValues, XHuman(), 1, 5);
    std::thread th2(&XHuman::eraseValues, XHuman(), 1);
    th1.join();
    th2.join();
    return 0;
}

std::threadconstructor copies or moves its arguments. std::mutex 既不可复制也不可移动,因此将其作为 XHuman 的非静态数据成员包括在内使得 class 不可复制并且不可移动的。这就是您所看到的错误的原因。

您可以通过传递指针或对 XHuman 实例的引用来绕过它。

XHuman one, two;
std::thread th1(&XHuman::addValues, &one, 1, 5);
std::thread th2(&XHuman::eraseValues, std::ref(two), 1);