использование семантики перемещения для инициализации члена класса в конструкторе - PullRequest
2 голосов
/ 20 апреля 2019

Я изучаю многопоточность на C ++, и я написал простой класс, который содержит частный объект std::mutex для синхронизации при вызове функции-члена:

#include <mutex>
#include <iostream>

class SynchClass
{
public:
    SynchClass() {}
    void inline SynchronizedInterfaceFunction();    
private:
    std::mutex mMutex;
};

void inline SynchClass::SynchronizedInterfaceFunction()
{
    std::lock_guard<std::mutex> lock(mMutex);

    for (int i = 0; i < 10; i++) 
        std::cout << "thread n: " << std::this_thread::get_id() << " inside function" << std::endl; 

    std::cout << std::endl;
}

Теперь у этой функции естьdelete d конструктор копирования и оператор копирования, поскольку std :: mutex можно перемещать, но нельзя копировать / назначать.

Поэтому я предоставляю классу конструктор перемещения (который не генерируется компилятором автоматически):

class SynchClass
    {
    public:
        // ... other members as before
        SynchClass(SynchClass &&rhs) : mMutex(std::move(rhs.mMutex)) {}

    };

, но когда я добавляю эту строку, компилятор жалуется, что я пытаюсь вызвать конструктор удаленных копий std::mutex:

In file included from main.cpp:5:0:
SynchClass.h: In constructor 'SynchClass::SynchClass(SynchClass&&)':
SynchClass.h:8:61: error: use of deleted function 'std::mutex::mutex(const std::mutex&)'
  SynchClass(SynchClass &&rhs) : mMutex(std::move(rhs.mMutex)) {}
                                                             ^
In file included from C:/Program Files/mingw64/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/mutex:43:0,
                 from main.cpp:2:
C:/Program Files/mingw64/lib/gcc/x86_64-w64-mingw32/7.2.0/include/c++/bits/std_mutex.h:97:5: note: declared here
     mutex(const mutex&) = delete;

, но я использую std::move для приведения lvalue к rvalue, поэтому должен вызываться конструктор перемещения std :: mutex.

Чего мне не хватает?

1 Ответ

5 голосов
/ 20 апреля 2019

std::mutex не копируется и не может быть перемещен. У него нет конструктора перемещения или присваивания. Требования к библиотеке для mutex:

33.4.3.2 Типы мьютекса [thread.mutex.requirements.mutex]
3 Типы мьютексов должны быть DefaultConstructible и Destructible. Если инициализация объекта Тип мьютекса завершается ошибкой, должно быть выброшено исключение типа system_error. Типы мьютекса не должны копироваться или подвижный.

Если вы хотите, чтобы ваш класс двигался конструктивно, вам нужно будет добавить еще один слой косвенности в какой-то момент, например, используя std::unique_ptr<std::mutex>.

...