抽象线程相关的STL和Boost类型和方法

时间:2013-09-09 10:07:49

标签: c++ multithreading boost c++11 stl

我正在将线程库的一部分从C ++ 03移动到C ++ 11,但是我希望它与Boost兼容,作为不同用户的选项有C ++ 11编译器。由于C ++ 11 STL和Boost 1.54基本上具有相同的界面(至少对于我感兴趣的部分而言),所以有这样的东西会很好:

#ifdef USING_BOOST
#define NAMESPACE boost
#else
#define NAMESPACE std
#endif

typedef NAMESPACE::mutex MyLibrary::Mutex;
typedef NAMESPACE::condition_variable MyLibrary::ConditionVariable;
...

问题来自模板,例如unique_lock。更好的方法是:

#define TYPEDEF(WHAT, AS) typedef LIBPREFIX::WHAT AS

#define TYPEDEF_T(WHAT, AS)                 \
    template <typename T>                   \
    struct AS                               \
    {                                       \
        typedef LIBPREFIX::WHAT<T> type;    \
    };

TYPEDEF( thread, Thread );
TYPEDEF( mutex, Mutex );
TYPEDEF( condition_variable, ConditionVariable );

TYPEDEF_T( lock_guard, LockGuard );
TYPEDEF_T( unique_lock, UniqueLock );
TYPEDEF_T( shared_ptr, SharedPtr );

但是我必须这样使用它:

LockGuard<Mutex>::type lock(...);

E.g。我不想一直写::打字。

另外,我想覆盖make_shared函数,即按如下方式映射:

MyLibrary::MakeShared<T> --> NAMESPACE::make_shared<T>

其中NAMESPACE要么是'std&#39;或者&#39;提升&#39;我想这就像

#define USING(WHAT) using NAMESPACE::WHAT
USING( make_shared );

不是一个可行的选择......对吧?

覆盖整个boost名称空间不是解决方案,因为Boost的其他部分可以在代码中使用。实现这一目标的最佳方法是什么?

谢谢!

3 个答案:

答案 0 :(得分:4)

您只需通过using声明将相应的名称导入名称空间:

namespace MyLibrary {

#ifdef USING_BOOST
  using boost::thread;
  using boost::unique_lock;
  using boost::make_shared;
#else
  using std::thread;
  using std::unique_lock;
  using std::make_shared;
#endif

}

这适用于所有名称:类,函数和模板。

答案 1 :(得分:1)

使用命名空间别名:

#ifdef USING_BOOST
namespace mt = boost;
#else
namespace mt = std;
#endif

现在您可以参考mt::condition_variable,编译器将看到相应命名空间中的那个。

答案 2 :(得分:0)

最简单的选择不是继续使用提升吗?这样可以避免为自己做不必要的工作。如果不这样做,为什么不只是为你想从一个库或另一个库中选择的类型输入typedef:

namespace foo {
#ifdef USING_BOOST
    typedef boost::mutex       mutex;
    typedef boost::scoped_lock mutex_lock;
#else
    typedef std::mutex       mutex;
    typedef std::unique_lock mutex_lock;
#endif
}

foo::mutex myMutex;