std::define_static_array

来自cppreference.com
< cpp | meta
在标头 <meta> 定义
template< ranges::input_range R >
consteval std::span<const ranges::range_value_t<R>> define_static_array( R&& r );
(C++26 起)

将数组提升为静态存储。

N 为:如果 ranges::size(r) 是常量表达式,则为 static_cast<std::size_t>(ranges::size(r));否则为 std::dynamic_extent。其效果等价于:

using T = ranges::range_value_t<R>;
std::meta::info array = std::meta::reflect_constant_array(r);
if (std::meta::is_array_type(std::meta::type_of(array)))
    return std::span<const T, N>(std::meta::extract<const T*>(array),
                                 std::meta::extent(std::meta::type_of(array)));
else
    return std::span<const T, N>(static_cast<const T*>(nullptr), 0);

参数

r - 一个 input_range,其元素为可复制构造且具有结构式类型

返回值

如果 r 的大小不为零,则返回一个从类型为 const T[N] 的数组构造的跨度(其中 Tranges::range_value_t<R>Nr 的大小)。数组的每个元素均以 std::meta::reflect_constant(static_cast<T>(*it)) 所表示的值或对象进行初始化,其中 it 是指向 r 中对应元素的迭代器。

否则(r 的大小为零),返回一个空跨度。

注解

作为模板形参对象,结果数组对象(如果存在)具有静态存储期。具有模板实参等价内容的范围对应同一个数组对象。

该数组对象是一个可能非唯一的对象

示例

Compiler-explorer link.

#include <algorithm>
#include <meta>
#include <print>
#include <vector>

constexpr std::vector<double> precompute_angles(std::size_t size)
{
    std::vector<double> angles(size);
    for (int i{}; double& angle : angles)
        angle = 360.0 / size * i++;
    
    return angles;
}

consteval std::span<const double> precompute_angles_arr(std::size_t size)
{
    std::vector<double> angles = precompute_angles(size);
    return std::define_static_array(angles);
}

int main()
{
    // std::vector<double> angles = precompute_angles(7);
    //     错误:调用 consteval 函数 ‘precompute_angles(7)’ 不是常量表达式
    //            因为它指代了 ‘operator new’ 的结果

    std::span<const double> angles = precompute_angles_arr(7);
    for (double angle : angles)
        std::print("{:.1f} ", angle);

    std::println();
}

输出:

0.0 51.4 102.9 154.3 205.7 257.1 308.6

参阅

将编译期字符串提升为静态存储,返回指向该静态字符串首字符的指针
(函数模板) [编辑]
将编译期值提升为静态存储,返回指向该静态对象的指针。
(函数模板) [编辑]
将编译期数组提升为静态存储,返回表示该静态数组的反射
(函数模板) [编辑]