big*_*iao 7 c++ constexpr c++11
在cppref中,它给出了常量初始化的语法:
static T & ref = constexpr;
static T object = constexpr;
Run Code Online (Sandbox Code Playgroud)
这是我的两个问题:
一个左值引用怎么可能T &没有const绑定到a constexptr,它是常量且不可修改的?
我试着提供一些例子,但失败了:
static int& ref = 6; //error, need a `const`
constexpr int a = 6; static int& ref = a; //error, need a `const`
Run Code Online (Sandbox Code Playgroud)
对于持续初始化的对象是否必须是const/ static?在标准中它说:
执行恒定初始化如果与静态或线程存储持续时间的变量或临时对象由恒定初始化为实体初始化.
这里标准没有将obj指定为const-qualified/ static-qualified.
小智 6
试图说的是
static int a;
static int & ref = a;
static_assert(&a == &ref, "");
Run Code Online (Sandbox Code Playgroud)
没关系.初始化是一种常量初始化的形式,因为a当作为左值(但仅作为左值!)进行求值时,它&a == &ref是一个常量表达式,因此,它是一个求值为的常量表达式true.
比较这个
void f() {
int a;
static int & ref = a;
static_assert(&a == &ref, "");
}
Run Code Online (Sandbox Code Playgroud)
这是无效的.尽管初始化在ref技术上是有效的,但只要函数返回它就会成为悬空引用.下次输入该函数时,将int a创建一个新对象.因此,&a == &ref不保证评估true.它不是一个常量表达式,如果进行求值,它将具有未定义的行为.
的混乱是由于命名:术语恒定在恒定的初始化 [basic.start.static]/2和常量表达式 [expr.const]意味着在没有编译器的英勇努力(1)编译时评估.这与常量对象的概念不同,这意味着一旦定义,对象的值就不会改变.
为了说明编译时评估的限制,让我们看看这段代码的汇编:
//case 0
int i0 = 5;
int j0 = i0;//no compil-time initialized
//case 1
const int i1=5;
int j1=i1; //compil-time initialized
//case 2
extern const int i2=5;
int j2=i2; //compile-time initialized
//case 3
extern const int i3;
int j3=i3; //no compil-time initialization
//case 4
extern const int i4;
int j4=i4; //no compil-time initialization
const int i4=5;
Run Code Online (Sandbox Code Playgroud)
由gcc 7.3生成的程序集:
_GLOBAL__sub_I_example.cpp: # @_GLOBAL__sub_I_example.cpp
mov eax, dword ptr [rip + i0]
mov dword ptr [rip + j0], eax
mov eax, dword ptr [rip + i3]
mov dword ptr [rip + j3], eax
mov dword ptr [rip + j4], 5
ret
Run Code Online (Sandbox Code Playgroud)
发生了什么:
(1)原则是语言不应太复杂,无法编译.我只是回收了模板论证演绎标准的措辞,其中术语英雄的努力似乎很明显.应用相同的原则来定义什么是常量表达式.
| 归档时间: |
|
| 查看次数: |
295 次 |
| 最近记录: |