Как передать только мьютекс в параметр конструктора 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, который в настоящее время не реализует вывод аргумента шаблона класса для шаблонов псевдонимов .