gpt4 book ai didi

c++ - 比较两个constexpr指针不是constexpr吗?

转载 作者:行者123 更新时间:2023-12-02 15:17:32 25 4
gpt4 key购买 nike

我正在寻找一种在编译时将类型映射到数值的方法,理想情况下不使用 this 中建议的哈希值。回答。

因为指针可以是 constexpr ,我试过这个:

struct Base{};
template<typename T> struct instance : public Base{};

template<typename T>
constexpr auto type_instance = instance<T>{};

template<typename T>
constexpr const Base* type_pointer = &type_instance<T>;

constexpr auto x = type_pointer<int> - type_pointer<float>; // not a constant expression

gcc 和 clang 都拒绝此代码,因为 type_pointer<int> - type_pointer<float>不是常量表达式,请参阅 here ,例如。

为什么呢?

我可以理解,两个值之间的差异从一个编译到下一个编译并不稳定,但在一个编译内,它应该是 constexpr ,恕我直言。

最佳答案

两个不指向同一数组或同一对象(包括前一个数组/对象)的非空指针相减是未定义的行为,请参阅 [expr.add] C++17 标准(最终草案)的(特别是第 5 段和第 7 段)。

如果计算的话,将具有核心未定义行为的表达式[1]从不常量表达式,请参阅[expr.const]/2.6 .

因此type_pointer<int> - type_pointer<float>不能是常量表达式,因为这两个指针指向不相关的对象。

type_pointer<int> - type_pointer<float>不是常量表达式,它不能用于初始化 constexpr变量如

constexpr auto x = type_pointer<int> - type_pointer<float>;

尝试使用非常量表达式作为 constexpr 的初始值设定项变量使程序格式错误,并要求编译器打印诊断消息。这就是您看到的错误消息。

基本上,当核心未定义行为出现在纯编译时上下文中时,编译器需要对其进行诊断。

可以看到,如果指针指向同一个对象,则不会出错,例如:

constexpr auto x = type_pointer<int> - type_pointer<int>;

这里的减法是明确定义的,并且初始化器是一个常量表达式。因此代码将编译(并且不会有未定义的行为)。 x将具有明确定义的值 0 .

<小时/>

请注意,如果您创建 xconstexpr编译器将不再需要诊断未定义的行为并打印诊断消息。因此它可能会编译。

减去不相关的指针仍然是未定义行为,而不仅仅是未指定行为。因此,您将失去对最终程序的功能的任何保证。这不仅意味着您将获得 x 的不同值。在代码的每次编译/执行中。

<小时/>

[1] 核心未定义行为这里指的是核心语言中的未定义行为,与由于使用标准库而导致的未定义行为形成对比。 未指定为库指定的未定义行为是否会导致(否则为常量)表达式不是常量表达式,请参阅 [expr.const]/2 中示例之前的最后一句.

关于c++ - 比较两个constexpr指针不是constexpr吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59592046/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com