我喜欢跨度,所以我在各处使用gsl::span
。但是-在C ++ 20中,它将改为std::span
* 。我使用std::optional
,但对于C ++ 14代码,它必须为std::experimental::optional
。依此类推。
在这些变体(有时可能是两个以上)之间进行编译时选择的方式是一种惯用的,可以证明未来发展的方式,因此我的实际代码只能使用一个编译成以下代码的令牌序列正确选择的跨度,还是可选的,或其他类似的结构?
注意:我想避免污染全局名称空间。
*好吧,从技术上讲,我以后也可以使用gsl::span
,但是这个问题的想法是在标准可用时使用标准中的内容,并在此之前使用最接近的替代方法。
答案 0 :(得分:2)
我通常使用这样的东西:
#if some_kind_of_test_here_not_necessarily_a_macro
namespace stdx = std;
#elif some_other_test_here
namespace stdx = std::experimental;
#else
#error "Some Message"
#endif
现在在您的代码中只需使用:
stdx::span mySpan;
答案 1 :(得分:1)
这个问题是错误的,因为即使存在这样的“令牌序列”,也不能保证两个备选方案具有相同的表现。
考虑experimental::optional
与std::optional
。如果T
是可复制的,则在C ++ 17上的缺陷报告之后,需要可复制。 experimental::optional
不是。如果您依靠它来构建C ++ 17,则不知道它是否会与C ++ 14兼容。
gsl::span
的问题不大,因为GSL实现很可能会跟踪std::span
在C ++ 20中的更改。
但是,如果您坚持这样做,C ++ 20将使功能测试宏成为必需的。因此,您可以使用这样的宏技术:
#include <version>
#ifdef <insert span test macro here>
#include <span>
template<typename T, std::ptrdiff_t N>
using span = std::span<T, N>;
#else
#include <gsl/span>
template<typename T, std::ptrdiff_t N>
using span = gsl::span<T, N>;
#endif
当然,这里的问题是您必须包括<version>
,它本身是C ++ 20标头。因此,此代码只能与至少部分符合C ++ 20的编译器一起使用。
答案 2 :(得分:0)
一种方法是在迁移名称空间中使用包含合适的using
别名的迁移标头,例如:
#if __cplusplus < 201402L
#include <experimental/optional>
namespace mig {
template <typename T>
using optional = std::experimental::optional<T>;
}
#else
#include <optional>
namespace mig {
template <typename T>
using optional = std::optional<T>;
}
#endif
在迁移时,您将包括相应的标头,并使用mig::optional<T>
作为您的代码,这些代码可以通过optional
-du-jour与其他代码愉快地交互。兼容性问题消除后,您可以在适当的时候替换您的自定义资格。但是请注意,这些定义之间存在一些差异,即您需要坚持使用通用功能。
答案 3 :(得分:0)
@MartinYork方法的一种改编(希望)在单一构造级别而不是整个命名空间级别起作用:
#if __cplusplus >= 202001L
#include <span>
namespace stdx {
template <class ElementType, std::ptrdiff_t Extent = std::dynamic_extent>
using span = std::span<ElementType, Extent>;
} // namespace stdx
#else
#include <gsl/span>
namespace stdx {
template <class ElementType, std::ptrdiff_t Extent = gsl::dynamic_extent>
using span = std::span<ElementType, Extent>;
} // namespace stdx
#endif // __cplusplus >= 202001L