在C++ 11中,引入了一个新功能,程序员可以在类的定义中初始化类成员变量,请参阅下面的代码:
struct foo
{
int size = 3;
int id = 1;
int type = 2;
unsigned char data[3] = {'1', '2', '3'};
};
Run Code Online (Sandbox Code Playgroud)
这个初始化是在编译期间发生的,还是这个特性只是语法糖和成员变量在默认构造函数中初始化?
Nik*_*iou 27
首先是,如前所述,它是语法糖.但是由于规则可能太难以记住,这是一个逻辑实验,可以帮助您弄清楚在编译时发生了什么,什么不是
你有你的c ++ 11类,它在类初始化器中有特色
struct foo { int size = 3; };
Run Code Online (Sandbox Code Playgroud)
另一个课程将帮助我们进行实验
template<int N>
struct experiment { enum { val = N }; };
Run Code Online (Sandbox Code Playgroud)
让我们的假设H0是初始化确实在编译时发生,然后我们可以写
foo a;
experiment<a.size> b;
Run Code Online (Sandbox Code Playgroud)
没有运气,我们无法编译.有人可能会说失败是由于foo::size
不稳定所以让我们试试
struct foo { const int size = 3; }; // constexpr instead of const would fail as well
Run Code Online (Sandbox Code Playgroud)
再次,正如gcc告诉我们的那样
'a'的值不能用于常量表达式
实验b;
或者(更清楚地)视觉工作室2013告诉我们
错误C2975:'N':'example'的模板参数无效,是预期的编译时常量表达式
因此,我们必须丢弃H0并推断初始化不会在编译时发生.
有一种旧的语法可以解决这个问题
struct foo { static const int size = 3; };
Run Code Online (Sandbox Code Playgroud)
现在这个编译但要注意这在(技术上和逻辑上)不再在类初始化中.
我不得不撒谎以表达观点,但现在揭露全部真相:消息错误意味着这a
是真正的问题.你看,因为你有一个对象的实例(Daniel Frey也提到了这个),所以必须初始化内存(对于成员)(在运行时).如果成员是(const
)static
,就像在最后一个例子中那样,它不是(ny)类的子对象的一部分,你可以在编译时进行初始化.
归档时间: |
|
查看次数: |
4412 次 |
最近记录: |