如何仅将互斥量传递给 lock_guard 构造函数参数

How to pass only mutex to lock_guard constructor parameter

像这样声明储物柜时,

lock_guard Locker(mLocker);


我希望编译器检测 MLocker 是否为互斥量。

为了实现这一点,我使用了概念要求并定义如下。

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>;


如上,互斥锁针对类型T进行了验证,类型T的std::lock_guard通过using关键字别名。

但是当使用该别名 (expLock) 声明储物柜时。

std::recursive_mutex mutex_Lock;
expLock Locker(mutex_Lock); // error : No argument list for alias template expLock.


上面的代码导致编译错误。

似乎 std::lock_guard 构造函数的显式关键字被忽略了,因为下面的代码强制类型 T 为 std::lock_guard。

template <class T> requires is_mutex<T> using expLock = std::lock_guard<T>;
// 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;
};


当然,如果如下所示在alias(expLock)中指定类型T,则不会出现编译错误。

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构造函数参数?

我应该像std::lock_guard那样定义一个新的储物柜class吗? 要么 我需要修复别名吗?

也是这样还是有新的解决办法?



此问题已在下面的评论中得到解答。

According to cppreference, MSVC implemented P1814 after 19.27*, so if your MSVC version is newer than 19.27*, your code will compile when use the /std:c++latest flag. – 康桓瑋

If the MSVC of the current project is version 19.27 or later, you can omit the template argument list for the using keyword. However, if you are using Visual Studio's Intellisense, Intellisense may display an error message. If a template argument list error message for the using keyword is popped up in MSVC 19.27 or later, This error message may be caused by the Intellisense patch not based on the MSVC version. Apart from the error message that Intellisense pops up, the build works without any problem. - 정명준

首先,您对is_mutex的概念定义不正确。它只会检查 requires 子句中 is_same_vvalidity 而不会对其进行评估。您需要将其定义为:

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>;

Above code causes a compile error.

其实上面的代码就是well-formed in C++20. I guess you are using Clang, which currently does not implement Class Template Argument Deduction for Alias Templates.