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 закончил выполнение.

Другие вопросы по тегам