M.M*_*M.M 12 c++ endianness constexpr c++20
从 C++20 开始,我们可以有:
constexpr bool is_little_endian = std::endian::native == std::endian::little;
Run Code Online (Sandbox Code Playgroud)
如果可用,我希望有执行此操作的代码,否则执行运行时检测。这可能吗?
也许代码看起来像:
template<bool b = std_endian_exists_v> constexpr bool is_little_endian;
template<> constexpr bool is_little_endian<true> = std::endian::native == std::endian::little;
template<> constexpr bool is_little_endian<false> = runtime_detection();
Run Code Online (Sandbox Code Playgroud)
我知道__cplusplus通过预处理器进行测试是可能的,但是 C++20 中的编译器阶段在各个阶段都支持,因此这在任一方向都不是可靠的指标。
Bar*_*rry 10
我知道
__cplusplus通过预处理器进行测试是可能的,但是 C++20 中的编译器阶段在各个阶段都支持,因此这在任一方向都不是可靠的指标。
的确!事实上,这就是为什么我们现在有一种全新的方法来检测处于不同发布阶段的编译器的功能支持:功能测试宏!如果您查看SD-FeatureTest,就会发现与标准中采用的每种语言和库功能相对应的大型宏表,一旦采用了某个功能,每个宏将使用指定的值进行定义。
在您的特定情况下,您想要__cpp_lib_endian.
现在库宏的问题在于我们在添加放置它们的位置之前就开始添加它们——这将是<version>. 如果您使用的编译器具有<version>(将是 gcc 9+,带有 libc++ 的 clang 7+,并且我不知道 MSVC),您可以只包含它。但它可能不会,因此您可能还必须尝试包含正确的标头(在本例中为<bit>)。
#if __has_include(<bit>)
# include <bit>
# ifdef __cpp_lib_endian
# define HAS_ENDIAN 1
# endif
#endif
#ifdef HAS_ENDIAN
constexpr bool is_little_endian = std::endian::native == std::endian::little;
#else
constexpr bool is_little_endian = /* ... figure it out ... */;
#endif
Run Code Online (Sandbox Code Playgroud)
虽然这样做可能更好:
#ifdef HAS_ENDIAN
using my_endian = std::endian;
#else
enum class my_endian {
// copy some existing implementation
};
#endif
constexpr bool is_little_endian = my_endian::native == my_endian::little;
Run Code Online (Sandbox Code Playgroud)