C++ ScopeTryLock Macro
Привет, у меня есть мьютекс, и я хотел бы сделать TryScopeLock, который будет использоваться как
if (ScopeTryLock(mutex))
{
...
}
Идея состоит в том, что, если мьютекс может быть заблокирован, он вводится и в операторе if. В противном случае его пропустили.
Я пытаюсь использовать этот макрос и класс, чтобы достичь его
#define ScopeTryLock(lock) (_ScopeTryLock &lock = _ScopeTryLock::MakeTryLock(lock, __FILE__, __LINE__).tryToLock()).ownsLock()
class _ScopeTryLock
{
bool didLock;
const char *file;
const int line;
public:
static _ScopeTryLock MakeTryLock(Mutex& m, char* file, int line)
{
return _ScopeTryLock(m, file, line);
}
_ScopeTryLock(Mutex& m, char* file, int line) : mutex(m), didLock(false), file(file), line(line){}
~_ScopeTryLock()
{
if (didLock)
{
mutex.Unlock((char *) file, line);
}
}
_ScopeTryLock &tryToLock()
{
if (mutex.TryLock((char *)file, line))
{
didLock = true;
}
return *this;
}
bool ownsLock()
{
return didLock;
}
protected:
Mutex& mutex;
};
Проблема в том, что я не могу понять правильный макрос, чтобы заставить эту работу работать так, как я хочу. я пытался
#define ScopeTryLock(lock) _ScopeTryLock::MakeTryLock(lock, __FILE__, __LINE__).tryToLock().ownsLock()
но это не сработало, как кажется, вызывает деструктор, когда вводит оператор if, а это не то, что я хочу. Я также хочу держаться подальше от использования кучи. Есть идеи, как заставить это работать?
редактировать:
извините, я должен указать, что это с ++11. Также у меня нет большой гибкости с мьютексом, который я использую. У мьютекса есть.Try(), который будет возвращать true, если блокировка была успешной, и false, если это не так. Это мой единственный механизм взаимодействия с мьютексом (конечно, я могу заблокировать и разблокировать его). Я действительно хотел бы выяснить немного магии с ++, чтобы заставить эту работу работать так, как я хочу в условии if. Может быть, это невозможно, я думаю:(
1 ответ
Если вы используете C++17, вы можете использовать новую версию if
оператор, в котором вы можете объявить переменную на время кода, управляемого if.
#define ScopeTryLock(mutex) ScopeTryLock lock(ScopeTryLock::MakeTryLock(lock, __FILE__, __LINE__)); lock.tryToLock().ownsLock()
(Примечание. Вокруг этого скобки нет, и точка с запятой отделяет оператор init от условия.) Это объявит переменную lock
что останется в сфере действия на время if
заявление (и else
если есть).
Затем, когда вы используете его в операторе if
if (ScopeTryLock(mutex))
это создаст переменную (по имени lock
) это не будет уничтожено, пока тело if
закончил выполнение.