像申报储物柜时,
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 通过使用关键字进行了别名。
但是当使用该别名(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 这样的新 Locker 类吗?或者我需要修复别名吗?
也是这样还是有新的解决方案?
这个问题已经在下面的评论中得到了回答。
根据 cppreference,MSVC 在 19.27* 之后实现了 P1814,所以如果您的 MSVC 版本比 19.27* 新,您的代码将在使用 /std:c++latest 标志时编译。——康桓玮</p>
如果当前项目的 MSVC 是 19.27 或更高版本,则可以省略 using 关键字的模板参数列表。但是,如果您使用 Visual Studio 的 Intellisense,Intellisense 可能会显示错误消息。如果在 MSVC 19.27 或更高版本中弹出 using 关键字的模板参数列表错误消息,则该错误消息可能是由于 Intellisense 补丁不基于 MSVC 版本。除了 Intellisense 弹出的错误消息外,构建工作没有任何问题。- 정명준