Как передать только мьютекс в параметр конструктора lock_guard

Когда объявляют шкафчик как,

      lock_guard Locker(mLocker);


Я хочу, чтобы компилятор определил, является ли mLocker мьютексом.

Чтобы реализовать это, я использовал концепцию «требует» и определил ее, как показано ниже.




Как и выше, мьютекс был проверен для типа T, а std ::lock_guard для типа T был псевдонимом с помощью ключевого слова.

Но при объявлении шкафчика с этим псевдонимом (expLock).



Вышеупомянутый код вызывает ошибку компиляции.

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


      // CLASS TEMPLATE lock_guard
template <class _Mutex>
class _NODISCARD lock_guard { // class with destructor that unlocks a mutex
public:
    using mutex_type = _Mutex;

    explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) { // construct and lock
        _MyMutex.lock();
    }

    ...

private:
    _Mutex& _MyMutex;
};


Конечно, если тип T указан в псевдониме (expLock), как показано ниже, ошибки компиляции не возникает.

      std::recursive_mutex mutex_Lock;
expLock<std::recursive_mutex> Locker(mutex_Lock);


Но я хочу, чтобы приведенный ниже код работал без ошибок компиляции.

      template <typename T>
concept is_mutex = requires
{
  std::is_same_v<T, std::recursive_mutex>;
};
      template <class T> requires is_mutex<T> using expLock = std::lock_guard<T>;
      std::recursive_mutex mutex_Lock;
expLock Locker(mutex_Lock); // error : No argument list for alias template expLock.


Как передать только мьютекс в параметр конструктора lock_guard?

Должен ли я определять новый класс Locker, например std ::lock_guard? или мне нужно исправить псевдоним?

Это тоже или есть новое решение?

1 ответ

Во-первых, ваша концепция is_mutexнеправильно определяется. Он только проверит действительностьis_same_vв предложении требует, не оценивая его. Вам нужно определить его как:

      template <typename T>
concept is_mutex = requires { requires std::is_same_v<T, std::recursive_mutex>; };

Или просто:

      template <typename T>
concept is_mutex = std::is_same_v<T, std::recursive_mutex>;

Код выше вызывает ошибку компиляции.

На самом деле приведенный выше код правильно сформирован на C++20. Я предполагаю, что вы используете Clang, который в настоящее время не реализует вывод аргумента шаблона класса для шаблонов псевдонимов .

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