Per*_*-lk 3 c++ memory-address constexpr c++14
严格按照C++ 14的规则,至少cppreference.com给出的规则,不是第(1)行是一个常量表达式吗?
constexpr const int* addr(const int& ir) { return &ir; }
constexpr const int* tp = addr(5); // (1)
Run Code Online (Sandbox Code Playgroud)
确实,它不是地址常量表达式,因为&ir它不是静态对象&ir的地址(在此上下文中是临时的地址,在编译时无法知道).
但它是一个核心常量表达式,因为它不违反任何后面列出的核心常量表达式规则,它没有关于获取对象地址的后续规则.
不,addr(5)不是一个常量表达式,因此发布的代码格式不正确.是的,你是正确的,这addr(5)是一个核心常量表达式.
我可以看到为什么你可以单独从cppreference页面思考核心常量表达式,整数常量表达式,转换常量表达式,文字常量表达式,引用常量表达式和地址常量表达式都是常量表达式的类型.但真正的定义在C++ 14 [expr.const]/4中给出:
甲常量表达式可以是一个glvalue芯常量表达式,其值指的是具有静态存储持续时间或于函数时,或prvalue芯常量表达式,其值是一个对象的对象,其中,该对象及其子对象:
引用类型的每个非静态数据成员是指具有静态存储持续时间或对象的对象,以及
如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址,该对象的地址超过此类对象的结尾,函数的地址或空指针值.
作为"核心常数表达"并没有多少直接影响; 它只是一个术语,用于帮助定义"整数常量表达式","转换的常量表达式T"和"常量表达式".并且"常量表达式"实际上描述了"核心常量表达式"描述的表达式的子集,而不是超集.
例如,要完成,使示例格式错误的段落([dcl.constexpr]/9)需要一个常量表达式,而不是核心常量表达式,作为初始化程序.
constexpr对象声明中使用的说明符将对象声明为const.这样的对象应具有文字类型并应初始化.如果它是由构造函数调用初始化的,那么该调用应该是一个常量表达式.否则,或者如果constexpr在引用声明中使用了说明符,则其初始值设定项中出现的每个完整表达式都应是常量表达式.[ 注意:用于转换初始化表达式和用于初始化的每个构造函数调用的每个隐式转换都是这种完整表达式的一部分.- 结束说明 ]