这基本上是关于DR 712的my prior question的延续。让我首先解释为什么我坚持要查看可能被认为是旧的东西,如C ++ 11标准,但我的问题在[C ++ 11]中已经很难理解[basic.def.odr]部分了,在我深入研究当前草案中的相同部分之前我想完全涵盖这一部分,在我看来,这个部分更加复杂
我Austing Hasting的先前问题的答案很棒,但我仍然有一点在C ++ 11的[basic.def.odr] / 2中不明确。考虑一下这个非常简单的例子:
const int i = 1;
int main()
{
int j = i;
}
来自C ++ 11 [{1}}中的[basic.def.odr] / 2,i
中的不是 odr-used
,因为int j = i;
是满足出现在常量表达式中的要求的对象,并且左值到右值的转换会立即应用于i
。这对我来说没有多大意义,因为i
在声明i
中被清晰地使用,正如在here显示的略微修改的代码中可以看到的那样,我强迫变量int j = i;
不能从编译的代码中优化。
当然,上面的推理肯定有问题,因为我不相信C ++ 11在这么简单的例子中可能是错的。再一次,我现在想念的是什么?
答案 0 :(得分:9)
我试图翻译我对标准的理解"用过"和"使用的一个定义规则"在这里更直观的东西。使用"以外的条款"和" ODR使用"不属于以下标准定义的术语。
使用ODR的东西基本上意味着"我们需要它来拥有身份"。这通常意味着有人正在引用它或指针。
如果您只需要某些内容的值,则不会总是使用ODR。编译时常量的值不需要标识。
在C ++中,身份基本上意味着"它实际上必须在某处存储"。
标准没有说"如果我们需要它来拥有身份而使用ODR,因为那时不同的编译器将有不同的规则来确定他们是否需要身份。例如,如果内联操作并且引用被省略,这是否意味着它不再需要身份?
因此,该标准描述了ODR使用的含义,并将其与所使用的值区分开来。
int j = i;
这不需要i
的身份。它只需要它的价值。 const int i = 1;
的值不会(在定义的行为下)发生变化。
int const* pj = &i;
此 需要一个身份。 i
的两个不同指针必须就i
在标准下的位置达成一致。
void foo( const int& x ) {
int j = x;
}
foo(i);
这也需要i
的身份。我们引用i
。尽管我们做的唯一事情就是引用它的价值,但该引用的(简短的,理论上的)存在意味着它具有一种身份。
const int a = 3; const int b = 4;
int i = (a<2)?a:b;
缺陷是,这需要a
和b
具有身份(它们使用ODR),因为?
与使用规则的交互。缺陷是说&#34;我们应该解决这个问题&#34;。
在该决议之后,该表达式只需要a
和b
的值,而不是他们的身份,因此他们不需要存储。
我们关心某些东西是否存储,因为需要存储的东西必须具有独特的定义点。它们基本上不能完全存在于头文件中。
请注意,对于C ++中的内联变量,我们可能不太关心这一点;在as-if规则下,如果没有人真正关注身份,则可以删除创建的内联存储位置。因为const&
可以&#34;意外地&#34;强制身份要求的东西只是有价值的令牌,这是一个很好的放松规则。