C风格数组能否像std::array一样返回迭代器并实现constexpr函数?
问题解答
1. C类型数组返回迭代器的实现
C风格数组的原生迭代器就是指向元素的指针,完全符合C++标准库的随机访问迭代器要求,和std::array的迭代器行为完全兼容,可以直接在所有标准库算法中通用。
你只需要把Func的返回类型修改为存储首尾迭代器的std::pair即可,修改后的代码如下:
std::pair<const int*, const int*> Func() noexcept { static int arr[] = {1, 2}; return {std::cbegin(arr), std::cend(arr)}; }
修改后的返回值和Func2、Func3的返回值用法完全一致,可直接传入std::for_each等标准算法使用,不需要额外适配。
2. 改造Func为constexpr函数的相关问题
static替换为constexpr编译失败的原因
C++中块级作用域的constexpr变量默认是自动存储期,和普通局部变量一致,函数执行结束后就会被销毁,此时返回它的指针/迭代器属于悬垂引用,标准明确禁止这种操作,因此编译器会直接报错。
而static修饰的局部变量属于静态存储期,生命周期和程序运行周期一致,返回它的指针/迭代器不会出现悬垂问题。
改造Func为constexpr函数的方法
需要满足两个要求:
- 使用C20及以上标准编译:C20才放开限制,允许
constexpr函数内部存在static/thread_local修饰的变量,且要求这类变量必须是常量初始化的。 - 静态数组本身满足常量初始化要求,你的示例中数组用字面量初始化,符合要求。
改造后的代码如下:
constexpr std::pair<const int*, const int*> Func() noexcept { static constexpr int arr[] = {1, 2}; return {std::cbegin(arr), std::cend(arr)}; }
如果使用C++17及更早的标准,不允许constexpr函数中出现static变量,无法直接改造为和Func2完全一致的constexpr实现,只能将C数组移到函数外部作为全局constexpr变量使用。
内容的提问来源于stack exchange,提问作者domoremath
相关产品推荐
相关产品推荐

