c++ - c++ constexpr指针和constexpr比较
问题描述
在以下代码中:
struct test{
struct Data{};
static constexpr const Data data1{};
static constexpr const Data data2{};
static constexpr const Data* pdata1 = &data1;
static constexpr const Data* pdata2 = &data2;
static constexpr const bool b1 = pdata1 == pdata2; // OK
static constexpr const bool b2 = pdata1 != pdata2; // OK
static constexpr const bool b3 = pdata1 < pdata2; // ERROR: is not a constant expression
};
编译器允许我将指针与==
和进行比较!=
。但是<
,>
导致编译器错误。为什么这样?
解决方案
比较两个不相关对象的地址有未指定的结果
[expr.rel]
3比较不相等的指向对象的指针定义如下:
如果两个指针指向同一数组的不同元素或其子对象,则指向具有较高下标的元素的指针比较大。
如果两个指针指向同一个对象的不同非静态数据成员,或者这些成员的子对象,递归地,如果两个成员具有相同的访问控制并且它们的类不是联盟。
否则,没有一个指针比较大于另一个。
4如果两个操作数 p 和 q 比较相等,
p<=q
并且p>=q
都产生 true,p<q
并且p>q
都产生 false。否则,如果指针 p 比较大于指针 q,则p>=q
,p>q
,q<=p
, 和q<p
都产生 true 并且p<=q
,p<q
,q>=p
, 和q>p
都产生 false。否则,每个运算符的结果都是未指定的。
并且明确禁止具有未指定结果的关系表达式出现在常量表达式中
[expr.const]
2表达式 e 是核心常量表达式,除非根据抽象机的规则对 e 的求值将求值以下表达式之一:
- ...
- 结果未指定的关系或等式运算符;或者
- ...
当编译器在常量表达式的求值中遇到禁止的情况时,它需要发出诊断。因此你得到一个错误。
始终牢记 C++ 标准是根据抽象机器定义事物的。常量表达式是那些在该抽象机器中具有明确定义的语义的表达式,因此可以在所有参数都已知的情况下“在编译时”进行评估。如果抽象机中未指定某些内容,则无法生成定义良好的常量表达式,因此被禁止。
推荐阅读
- node.js - 运行 npm run dev 时出错
- gradle - Gradle 在 build.gradle 中获取 Java 类路径
- php - yii2 没有使用 composer 安装正确的权限
- angular - 新的角度项目,生成新组件和选择器无法识别
- .net - Source 和 Log 属性必须匹配
- python - 在 Selenium 中不再在 DOM 中后切换回父框架
- mysql - mysql 中的变量 max_connections、interactive_timeout、connect_timeout 等不能满足我在 angular2+ 和 nodejs 中的问题
- asp.net-mvc - 无法使用 List ViewModel 呈现 PartialView
- c# - 处理 Microsoft.AnalysisServices 更新方法上的错误
- certificate - VOIP 服务无法在生产环境中运行,但在测试服务器中运行良好