如何正确使用标签调度来选择构造函数

Chr*_*oph 5 c++ constructor

我正在尝试为嵌入式系统实现一组互斥锁和锁类.我之前从未使用过标签调度,而且我不确定我是否做得对.boost文档中包含的描述只是这样:

struct input_iterator_tag { };
Run Code Online (Sandbox Code Playgroud)

并使用它来选择专门的模板功能.我没有模板,我只想根据标签的存在选择一个特定的构造函数:

// in mutex.h:

struct TryLock { };
// defined nowhere, i.e. there's no cpp file for this:
extern TryLock try_lock; 

template<typename MutexType>
class ScopedLock
{
  public:
    ScopedLock(MutexType& mtx) : m_mtx(mtx), m_acquired(true)
    {
      m_mtx.lock();
    }
    ScopedLock(MutexType& mtx, TryLock) : m_mtx(mtx)
    {
      m_acquired = m_mtx.tryLock();
    }
  ...
}
Run Code Online (Sandbox Code Playgroud)

在我的代码中的某个地方,我有一个我要锁定的互斥锁:

Mutex mtx;
ScopedLock<Mutex> lock(mtx, try_lock);
Run Code Online (Sandbox Code Playgroud)

这编译好并且有效.我只是好奇我是否可以摆脱它extern TryLock try_lock;,因为我的印象是它有点多余.

raz*_*zeh 3

如果将锁构造函数调用中的用法替换为临时的,则不需要 try_lock 的 extern 声明:

Mutex mtx;
ScopedLock<Mutex> lock(mtx, TryLock());
Run Code Online (Sandbox Code Playgroud)

否则,编译器会将 try_lock 的副本传递给构造函数,此时它将想要链接它。

当标准库需要这样做时,它使用constexpr

struct piecewise_construct_t { };
constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
Run Code Online (Sandbox Code Playgroud)