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

Abstracting thread-related STL and Boost types and methods

本文关键字:Boost 类型 方法 STL 线程 抽象      更新时间:2023-10-16

我正在将线程库的一部分从 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(...);

例如,我不喜欢一直写 ::type。

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

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

其中命名空间是"标准"或"提升"。我猜

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

不是一个可行的选择...右?

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

谢谢!

您可以通过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
}

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

使用命名空间别名:

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

现在您可以引用mt::condition_variable编译器将看到来自相应命名空间的那个。

最简单的选择不是继续使用boost吗?这样可以避免为自己做不必要的工作。如果做不到这一点,为什么不只为你想要从一个库或另一个库选择的类型使用 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;
相关文章: