比较两个constexpr指针不是constexpr吗? [英] Comparing two constexpr pointers is not constexpr?

查看:118
本文介绍了比较两个constexpr指针不是constexpr吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种在编译时将类型映射到数值的方法,理想情况下不使用此中提出的散列a>答案.

I am looking for a way to map types to numeric values at compile time, ideally without using a hash as proposed in this answer.

由于指针可以是constexpr,所以我尝试了以下方法:

Since pointers can be constexpr, I tried this:

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>不是常量表达式,请参见此处 ,例如.

Both gcc and clang reject this code because type_pointer<int> - type_pointer<float> is not a constant expression, see here, for instance.

为什么?

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

I can understand that the difference between both values is not going to be stable from one compilation to the next, but within one compilation, it should be constexpr, IMHO.

推荐答案

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

Subtraction of two non-null pointers which do not point into the same array or to the same object (including one-past-the-array/object) is undefined behavior, see [expr.add] (in particular paragraph 5 and 7) of the C++17 standard (final draft).

具有核心未定义行为的表达式 [1] 如果被评估为从不常量表达式,请参见

Expressions which would have core undefined behavior[1] if evaluated are never constant expressions, see [expr.const]/2.6.

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

Therefore type_pointer<int> - type_pointer<float> cannot be a constant expression, because the two pointers are to unrelated objects.

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

Since type_pointer<int> - type_pointer<float> is not a constant expression, it cannot be used to initialize a constexpr variable such as

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

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

Trying to use a non-constant expression as initializer to a constexpr variable makes the program ill-formed and requires the compiler to print a diagnostic message. This is what the error message you are seeing is.

基本上,编译器需要诊断在纯编译时上下文中出现的核心未定义行为.

Basically compilers are required to diagnose core undefined behavior when it appears in purely compile-time contexts.

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

You can see that there will be no error if the pointers are to the same object, e.g.:

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

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

Here the subtraction is well-defined and the initializer is a constant expression. So the code will compile (and won't have undefined behavior). x will have a well-defined value of 0.

请注意,如果将x设置为非constexpr,则不再需要编译器来诊断未定义的行为并打印诊断消息.因此,它很可能会编译.

Be aware that if you make x non-constexpr the compiler won't be required to diagnose the undefined behavior and to print a diagnostic message anymore. It is therefore likely to compile.

减去不相关的指针仍然是 undefined 行为,不仅是 unspecified 行为.因此,您将无法保证最终程序将执行的操作.这不仅意味着在每次编译/执行代码时,x的值都将不同.

Subtracting unrelated pointers is still undefined behavior though, not only unspecified behavior. Therefore you will loose any guarantee on what the resulting program will do. It does not only mean that you will get different values for x in each compilation/execution of the code.

[1] 核心未定义行为此处是指核心语言中的未定义行为,与使用标准库导致的未定义行为相反.对于该库指定的未定义行为是否导致(否则为常量)表达式不是常量表达式,这是未指定的,请参见

[1] Core undefined behavior here refers to undefined behavior in the core language, in contrast with undefined behavior due to use of the standard library. It is unspecified whether undefined behavior as specified for the library causes an (otherwise constant) expression to not be a constant expression, see final sentence before the example in [expr.const]/2.

这篇关于比较两个constexpr指针不是constexpr吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆