![](/img/trans.png)
[英]constexpr std::vector and constexpr std::string in C++20
[英]error while trying to compile .data() from std::array as a constexpr function in c++20
我试图在编译时计算一个数组以加快某些函数的速度,但我遇到了一个错误,我无法在 cppreference 的帮助下解决该错误。
代码归结为:
#include <cstddef>
#include <array>
template<typename T, size_t size>
constexpr auto giveArray()
{
std::array<T, size> arr;
for(size_t i = 0; i < size; ++i)
arr[i] = 0;
return arr;
}
constexpr auto arr = giveArray<int,10>().data();
在编译时:“$ g++ -std=c++20 code.cpp” on ubuntu 我收到错误 that.data() is not a constexpr function 虽然它确实是。 为什么我会收到此错误以及如何修复它,同时仍在编译时运行此 function 并仅存储一个指针,而不是 std::array object?
只存储一个指针,而不是 std::array object?
你不能。
C++ 的规则不会因为您的代码在编译时执行而暂停(实际上,不暂停这些规则是constexpr
代码的一半)。 该数组需要存在才能使指向它的指针有意义。 这意味着当有人使用该指针时,数组 object 需要继续存在。
获取指向被销毁的临时对象的指针将使该指针指向被销毁的 object。这在编译时代码和运行时代码中都是一样的。 使用该指针在编译时和在运行时一样不起作用。 事实上,它的功能较少,因为必须在编译时诊断 UB(这是访问该指针将引发的)并将其转化为编译错误。
你可以试试
constexpr auto a0 = giveArray<int,10>();
constexpr auto arr = a0.data();
我的意思是...
constexpr auto arr = giveArray<int,10>().data();
您尝试使用指向 memory 的指针初始化arr
,该指针之后立即释放。
您可以解决修复从giveArray()
收到的std::array
constexpr auto a0 = giveArray<int,10>();
所以arr
收到一个指向 memory 的指针,它在初始化后保持稳定
constexpr auto arr = a0.data();
要初始化constexpr
变量,您需要一个作为常量表达式的初始化器。 但是giveArray<int,10>().data();
不是常量表达式。
从这里开始:
常量表达式是指作为常量表达式(定义如下)的允许结果的实体的左值核心常量表达式,或者是其值满足以下约束的纯右值核心常量表达式:
- 如果该值是 class 类型的 object,则引用类型的每个非静态数据成员都引用一个实体,该实体是常量表达式的允许结果,
- 如果该值是指针类型,则它包含具有 static 存储持续时间的 object 的地址,这样的 object ([expr.add]) 末尾的地址,非立即数 function 的地址,或 null 指针价值,
- 如果该值是指向成员函数的指针类型,则它不会指定立即数 function,并且
- 如果该值是 class 的 object 或数组类型,则每个子对象都满足该值的这些约束。 如果一个实体是一个 object 和 static 的存储持续时间,它不是一个临时的 object 或者是一个临时的 882829995402888 其值满足上述约束,或者如果它是一个非立即的 function,则该实体是常量表达式的允许结果。
表达式giveArray<int,10>().data();
具有 prvalue 的值类别,因此它不是 glvalue 表达式。 这意味着它必须是“其值满足以下约束的纯右值核心常量表达式”才能成为常量表达式。 由于表达式的计算结果为指针类型,因此它必须满足以下条件:
- 如果该值是指针类型,则它包含具有 static 存储持续时间的 object 的地址,这样的 object ([expr.add]) 末尾的地址,非立即数 function 的地址,或 null 指针价值
在这种情况下,它不是那些东西,所以它不是常量表达式。 但是,如果您将代码更改为:
const auto my_array = giveArray<int,10>();
constexpr auto arr = my_array.data();
my_array
是一个全局变量,这意味着它有 static 个存储持续时间。 data()
返回指向该存储的指针,这使其成为常量表达式。
简而言之,这条规则使你在编译时执行代码时不能有一个指针值无效的指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.