Почему я не могу вернуть std :: lock_guard? Как я могу обойти это?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Почему я не могу вернуть std :: lock_guard? Как я могу обойти это?

Сообщение Anonymous »

Я пытаюсь вернуть std :: lock_guard по значению. Следующее работает нормально, используя онлайн -компилятор (Programiz), но в Visual Studio 2017 с использованием C ++ 17, lock1 () ниже не компилируется, потому что я пытаюсь ссылаться на удаленную функцию , и я должен обойти ее с помощью STD :: shared_ptr :

Код: Выделить всё

#include 
#include 

std::lock_guard lock1(std::mutex& m)
{
return std::lock_guard{ m };
}

std::shared_ptr lock2(std::mutex& m)
{
return std::make_shared(m);
}

int main()
{
std::mutex m1;
auto lg1 = lock1(m1);
std::mutex m2;
auto lg2 = lock2(m2);

return 0;
}
< /code>
Я делаю что -то не так, или MSVC виноват? Могу ли я обойти его без использования shared_ptr, например, используя std :: move 
? Я решил сделать это «указателем», но это неоправданно. Вот что я придумал. Обратите внимание на прокомментированный вариант lock () .

Код: Выделить всё

#include 
#include 
#include 
#include 
#include 

template
class ThreadSafePtr
{
std::shared_ptr ptr;
std::shared_ptr mutex;

public:
template
ThreadSafePtr(Args&&... args) : ptr{ std::make_shared(std::forward(args)...) }, mutex{ std::make_shared() } {}
ThreadSafePtr(ThreadSafePtr& orig) = default;
ThreadSafePtr& operator= (ThreadSafePtr& orig) = default;

class Lock
{
friend class ThreadSafePtr;
T& ref;
std::lock_guard lock;
Lock(ThreadSafePtr* tsptr) : ref{ *tsptr->ptr }, lock{ *tsptr->mutex } {}
public:
T& get() const { return ref; }
};

//Lock lock() { return Lock{ this }; }
std::shared_ptr lock()
{
return std::shared_ptr{ new Lock{ this } };
}
};

int main()
{
ThreadSafePtr map;
std::thread([map]() mutable -> void { map.lock()->get()[1] = 2; }).detach();
std::thread([map]() mutable -> void { map.lock()->get()[3] = 4; }).detach();

return 0;
}
(также, в зависимости от компилятора, пересылка аргументов в конструкторе может вызвать ошибку компилятора (но только если темафиптр фиксируется в лямбде), не уверенный, что происходит с этой проблемой, но снятие Copy Construction> (Args> ... избавляется от этой проблемы. Замена карты на std :: map может вызвать ошибку компилятора ... много интересных возможностей ...)

Подробнее здесь: https://stackoverflow.com/questions/795 ... -around-it
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»