How to properly use tag dispatching to pick a constructor

本秂侑毒 提交于 2019-12-10 15:14:30

问题


I'm trying to implement a set of mutex and lock classes for an embedded system. I've never used tag dispatching before, and I'm not sure if I'm doing it right. The description included in the boost documentation simply has this:

struct input_iterator_tag { };

and uses it to pick a specialized template function. I don't have a template, I just want to pick a specific constructor based on the presence of a tag:

// 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();
    }
  ...
}

and somewhere in my code I have a mutex which I want to lock:

Mutex mtx;
ScopedLock<Mutex> lock(mtx, try_lock);

This compiles fine and works. I'm just curious if I can get rid of the extern TryLock try_lock;, as I have the impression that it's somewhat superfluous.


回答1:


You won't need the extern declaration for try_lock, if you replace its usage in the lock constructor call with a temporary:

Mutex mtx;
ScopedLock<Mutex> lock(mtx, TryLock());

Otherwise the compiler will pass a copy of try_lock to your constructor, at which point it will want to link against it.

When the standard library needs to do this, it uses constexpr:

struct piecewise_construct_t { };
constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();


来源:https://stackoverflow.com/questions/20775285/how-to-properly-use-tag-dispatching-to-pick-a-constructor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!