使用gcc 4.7的可选和变体

时间:2018-01-26 22:49:02

标签: c++ c++11 gcc boost

我的代码应该用gcc 4.7编译, 哪个c ++ 11支持不错,但缺少c ++ 14和c ++ 17。

我想在我的代码中使用std::optionalstd::variant, 对于gcc 4.7 boost::optional的后备广告。

实现这一目标的标准方法是什么?

我看到两种变体:

  1. 变体周围的包装,它可能是宏的:boost::variant#define VARIANT_TYPE boost::variant
  2. 扩展namespace my_code { using variant = boost::variant }命名空间
  3. 第一个不好,因为我的代码会使用std, 而不是my_code::variant。第二个对我来说更清楚。

    std::variant可能是一般情况下的UB What are the reasons that extending the std namespace is considered undefined behavior?

    但我的具体案例呢?我知道2的确切版本是gcc,我可以在构建的配置阶段检查它。对于所有其他编译器/标准c ++库,我可以要求c ++ 17支持,而不是使用我的hack将variant/optional转换为boost::optional

    我还能抓住一些异国情调的问题吗?

2 个答案:

答案 0 :(得分:3)

您可以使用以下内容:

#ifdef NEED_WORKAROUND

# include <boost/optional.hpp>
# include <boost/variant.hpp>

namespace workaround
{
    namespace std
    {
        using boost::optional;
        using boost::variant;
    }
}
using namespace workaround;
#else
# include <optional>
# include <variant>
#endif

因此::std::variant<..>的使用将无效 但简单std::variant<..>的行为大多相似(您可能会遇到ADL问题)。

答案 1 :(得分:1)

接近你想要的东西的一种方法是找到一个为你做这件事的图书馆。

例如,Google's Abseil就是这样做的。不幸的是,他们的Supported Platforms页面显示他们需要gcc 4.8+,因为他们需要C ++ 11。但是,如果您可以满足他们的要求,那么您可以使用absl::optional代替std::optional,如果std::optional存在,则absl::optionalstd::optional,否则等同于std::optional

你写absl::optional而不是std::optional是无关紧要的;您的代码库的读者可以轻松地了解到他们是同一件事。&#34;我强烈建议不要将其放入std命名空间。

自己这样做是令人不愉快的,但并非不可能。你需要两件事:

  • 判断std::optional是否存在的方法
  • 另一个命名空间中std::optional的实现,它适用于您要支持的编译器版本(请注意boost版本不一定完全等同于{{1} }版本)

然后,您可以像在选项1中一样编写解决方法,并编写如下内容:

std