C++17中如何通过预处理器编译期构造std::array
解决方案
针对你遇到的编译期std::array构造问题,这里提供两种C++17下的可行方案:
方案一:预处理器宏+自定义constexpr make_array(推荐,新增依赖更便捷)
先实现一个兼容空参数的constexpr make_array模板,自动推导std::array的大小:
#include <array> #include <utility> // 处理带参数的情况 template <typename T, typename... Args> constexpr std::array<T, sizeof...(Args)> make_array(Args&&... args) { return {{std::forward<Args>(args)...}}; } // 特化空参数情况,返回大小为0的数组 template <typename T> constexpr std::array<T, 0> make_array() { return {}; }
再用预处理器宏批量生成依赖项的条件编译代码:
// 宏:如果对应依赖已启用,生成依赖名称字符串和逗号 #define ADD_DEPENDENCY(DEP_NAME) \ #if HAS_##DEP_NAME \ #DEP_NAME, \ #endif // 构造可用依赖的编译期数组 constexpr auto available_dependencies = make_array<const char*>( ADD_DEPENDENCY(DEPENDENCY1) ADD_DEPENDENCY(DEPENDENCY2) ADD_DEPENDENCY(DEPENDENCY3) // 新增依赖时,直接添加一行ADD_DEPENDENCY(新依赖名)即可 );
问题解决说明:
- 空依赖推导问题:当所有依赖都未启用时,
make_array<const char*>()会调用空参数特化,返回std::array<const char*, 0>,避免编译器无法推导模板参数的错误; - trailing comma问题:C++17允许函数调用参数末尾带逗号,即使最后一个启用的依赖后面有多余逗号,编译器会自动忽略,不会触发编译失败。
方案二:编译期计数+显式std::array(无需额外模板,适合依赖数量少的场景)
直接通过编译期计算依赖数量,显式指定std::array的模板参数:
#include <array> // 编译期计算启用的依赖总数 constexpr size_t enabled_dep_count = (HAS_DEPENDENCY1 ? 1 : 0) + (HAS_DEPENDENCY2 ? 1 : 0) + (HAS_DEPENDENCY3 ? 1 : 0); // 构造可用依赖数组 constexpr std::array<const char*, enabled_dep_count> available_dependencies = { #if HAS_DEPENDENCY1 "DEPENDENCY1", #endif #if HAS_DEPENDENCY2 "DEPENDENCY2", #endif #if HAS_DEPENDENCY3 "DEPENDENCY3", #endif };
问题解决说明:
- 空依赖推导问题:当无依赖启用时,
enabled_dep_count为0,std::array<const char*, 0>是合法的编译期数组; - trailing comma问题:C++初始化列表允许末尾带逗号,条件编译生成的列表即使最后有多余逗号,编译器也能正确处理。
内容的提问来源于stack exchange,提问作者Charlie Vanaret - the Uno guy
相关产品推荐
相关产品推荐

