比较两个constexpr指针不是constexpr吗?

问题描述 投票:4回答:1

我正在寻找一种在编译时将类型映射到数值的方法,理想情况下不使用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,恕我直言。

c++ pointers constexpr
1个回答
8
投票

两个未指向同一数组或同一对象(包括一个过去的对象)的非空指针的减法是未定义的行为。

如果被评估,将具有核心未定义行为的表达式是never常量表达式,请参见C ++ 17标准的[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 auto x = type_pointer<int> - type_pointer<int>;

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

© www.soinside.com 2019 - 2024. All rights reserved.