如何创建元素依赖于自身大小的constexpr数组?
如何创建依赖大小的constexpr计算数组
针对你需要生成依赖模板参数NUM_TRIANGLES大小、元素为n*angle的constexpr数组,有几种不同C++版本的实现方式:
方法1:C++20及以上(简洁版)
利用C++20的范围(Ranges)特性,结合std::views::iota生成整数序列,再通过transform计算目标值,最后用std::array::from_range构造数组:
#include <array> #include <ranges> #include <numbers> template <short NUM_TRIANGLES> constexpr auto circle() { constexpr float angle = (std::numbers::pi_v<float> / 2.0f) / NUM_TRIANGLES; constexpr auto angles = std::array<float, NUM_TRIANGLES>::from_range( std::views::iota(1, NUM_TRIANGLES + 1) | std::views::transform([angle](int i) { return static_cast<float>(i) * angle; }) ); // ... 后续逻辑 return angles; }
注:std::numbers::pi_v<float>是C++20标准中的π常量,比非标准的M_PI更推荐使用。
方法2:C++17及以上(兼容性好)
C++17允许constexpr函数内使用循环,直接手动填充数组即可,编译期会完成计算:
#include <array> #include <cmath> // 若使用M_PI,需在包含cmath前定义该宏(部分编译器要求) #define _USE_MATH_DEFINES #include <cmath> template <short NUM_TRIANGLES> constexpr auto circle() { constexpr float angle = (M_PI / 2.0f) / NUM_TRIANGLES; std::array<float, NUM_TRIANGLES> angles{}; for (short i = 0; i < NUM_TRIANGLES; ++i) { angles[i] = (i + 1) * angle; } // ... 后续逻辑 return angles; }
方法3:C++14及以上(模板元编程方式)
通过std::index_sequence生成编译期索引序列,再用折叠表达式展开计算:
#include <array> #include <cmath> #include <utility> #define _USE_MATH_DEFINES #include <cmath> namespace detail { template <short NUM_TRIANGLES, std::size_t... Is> constexpr std::array<float, NUM_TRIANGLES> make_angles(float angle, std::index_sequence<Is...>) { return {{ (Is + 1) * angle ... }}; } } template <short NUM_TRIANGLES> constexpr auto circle() { constexpr float angle = (M_PI / 2.0f) / NUM_TRIANGLES; return detail::make_angles<NUM_TRIANGLES>(angle, std::make_index_sequence<NUM_TRIANGLES>{}); }
内容的提问来源于stack exchange,提问作者Sheldon
相关产品推荐
相关产品推荐

