【问题标题】:C++ - how to type alias, typedef or wrap boost::variant?C++ - 如何键入别名、typedef 或包装 boost::variant?
【发布时间】:2014-07-27 06:30:29
【问题描述】:

我有一个可以很好地利用 Boost 的现有代码库。特别是,它在几个地方使用了不同风格的boost::variant

typedef boost::variant<double, int, unsigned int, size_t, bool> MBVariant;
typedef boost::variant<double, float> FPVariant;
// ...

它还使用其他 Boost 工具,例如:

typedef boost::shared_ptr<int> MyPtr;

我将此代码移植到不支持 Boost 的新平台,但必须与支持的平台一起维护。因此,我正在创建一个“Boost-wrapping”层,这将有助于消除 Boost 依赖:

#ifdef USE_BOOST
# include <boost/shared_ptr.hpp>
# include <boost/variant.hpp>

template <class T>
using my_shared_ptr = boost::shared_ptr<T>

// how to wrap variant?
// template <typename T0_, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)>
// using my_variant = boost::variant<T0_, ???>;

#else
# include <memory>

// in the absence of Boost, use something else like std::shared_ptr:
template <class T>
using my_shared_ptr = std::shared_ptr<T>

// wrap variant with something non-Boost
template <typename T0, /* uh... */>
class variant { /* ... */ };

#endif

现在客户端代码可以根据目标平台是否定义了 USE_BOOST 来使用 my_shared_ptr 或 my_variant:

typedef my_variant<double, int, unsigned int, size_t, bool> MBVariant;
typedef my_variant<double, float> FPVariant;
typedef my_shared_ptr<int> MyPtr;

我的问题是boost::variant 是一个类模板,它以递归类型列表的形式采用任意数量的参数类型。我不确定 typedef 或类型别名是否(或如何)可以处理这个问题。

有没有一种通用的方法来为此目的包装boost::variant

我知道我可以使用简单的 typedef 来为boost::variant特定 参数集提供新的类型名称,而且我目前没有大量的参数,所以这是可能的,但我对像boost::variant 这样的类型别名的一般方法非常感兴趣,同时尽可能避免使用预处理器,因为我需要将其集成到命名空间层次结构中。

【问题讨论】:

  • 您的编译器的 C++11 功能有多好?只是出于好奇,哪个平台不支持 Boost?
  • 我提供了一个定制的 Clang-3.0(禁用了标志 -std=c++11,因此只有标准的 C++0x 功能可用)。它用于虚拟 LLVM CPU,并且标准库的实现有限(例如,它缺少所有 iostream 内容等),这就是 Boost 存在很多问题的原因。与此同时,我正在尝试让 Boost 工作,但目前看起来并不好......
  • 顺便说一句,我不完全确定我了解 Clang 中的整个 C++11 支持 - 似乎默认支持某些功能,而某些功能需要 -std=c++11要指定。我不明白线是在哪里画的。我所知道的是,在这个自定义的 clang 版本中,我没有可用的 -std=c++11 开关,但其他 C++11 功能,如 auto、Ranged-for、类型别名工作正常。例如,强类型枚举不起作用。
  • 我最初的想法是,您可以使用可变参数模板来包装 boost::variants,但如果您没有 C++11 支持,那就行不通了。
  • namespaces 会不会是一种更简洁的方式来隐藏 boost/non-boost 依赖项?

标签: c++ templates boost boost-variant


【解决方案1】:
template <typename... T>
using my_variant = boost::variant<T...>

或者,我更喜欢

namespace library
{
    #if defined(HAS_BOOST)
        using boost::variant;
    #else
        using my_utils::variant;
    #endif
}

请注意,无论哪种情况,您都会遇到与 ADL 和专业化相关的问题。只要您使用 typedef,就无法隐藏条件的存在。

相反,您可以/应该编写自己的接口标头并换出实现文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多