如何在constexpr上下文中使用consteval函数参数?
consteval函数参数在constexpr上下文的使用困境
直接使用consteval参数的尝试
尝试在consteval函数中用参数作为std::array的模板参数,但编译器报错参数不是constexpr:
consteval auto foo(int size) { std::array<int, size> arr; // error: size is not constexpr auto const_size = std::meta::reflect_constant(size); auto array_type = std::meta::substitute(^^std::array, {^^int, const_size}); [:array_type:] arr; // error: array_type is not constexpr // 调用foo(10)时可以查看数组类型: // error: uncaught exception ‘&"std::array<int, 10>"[0]’ throw std::meta::display_string_of(array_type).data(); }
使用反射工具的替代方案
改用std::meta::reflect_constant_array或std::meta::define_static_array可以生成数组,但无法直接获取尺寸信息:
consteval auto foo(int size) { auto helper = std::ranges::views::iota(0, size); auto arr_refl = std::meta::reflect_constant_array(helper); auto arr = std::meta::extract<const int*>(arr_refl); // 调用foo(5)时可以查看静态数组: // error: uncaught exception ‘&"const int [5]{0, 1, 2, 3, 4}"[0]’ throw std::meta::display_string_of(arr_refl).data(); }
非类型模板参数的可行方案
改用非类型模板参数可以轻松实现需求:
template<int S> consteval auto foo() { std::array<int, S> arr; }
对反射实现与语言设计的观察
注意到可以用非constexpr值实例化非类型模板参数:std::meta::define_static_array的实现中,extract()会隐式实例化template<> __fixed_array,将非constexpr的r值存入静态存储(代码来自P3491R3):
// From P3491R3 template <typename T, T... Vs> inline constexpr T __fixed_array[sizeof...(Vs)]{Vs...}; template <ranges::input_range R> consteval auto reflect_constant_array(R&& r) -> info { auto args = vector<info>{^^ranges::range_value_t<R>}; for (auto&& elem : r) { args.push_back(reflect_constant(elem)); } return substitute(^^__fixed_array, args); } template <ranges::input_range R> consteval auto define_static_array(R&& r) -> span<ranges::range_value_t<R> const> { using T = ranges::range_value_t<R>; // 生成数组(info类型) auto array = meta::reflect_constant_array(r); // 转换为span return span<T const>(extract<T const*>(array), extent(type_of(array))); }
C++语言似乎刻意阻止将函数参数转为constexpr,或者将求值器已知的值反射为constexpr变量,目前不清楚这样设计的原因。即使借助静态反射,也只能通过extract()的技巧实现,但需要显式指定返回模板参数,相当于堵住了直接利用参数作为constexpr的路径。
内容的提问来源于stack exchange,提问作者Iris
相关产品推荐
相关产品推荐

