Gre*_*ree 5 c++ const language-lawyer
我与一个程序员进行了讨论,其主要观点是foo可以传递以下断言,具体取决于编译器.
#include <cassert>
const int i = 0 ;
void foo ( const int& i )
{
assert( &::i == &i ) ;
}
int main ( )
{
foo( i ) ;
}
Run Code Online (Sandbox Code Playgroud)
他告诉我,可以评估(&i)表达式以解决某些临时对象的问题.既然我有疑惑,我就在这里.对函数的引用如何传递给函数,如果在函数中我可以检查并做任何我想要的事情和参数的地址和预期的语义必须保留.例如
#include <initializer_list>
const int i = 0 ;
bool func ( const int & i )
{
return &::i == & i ;
}
int main ()
{
const int i = 0 ;
for ( const int * each : { &::i , &i , } )
if ( func( * each ) ) break ; // etc
}
Run Code Online (Sandbox Code Playgroud)
可能这种事情可能发生在某个地方,但不适用于这种情况.这就是我的想法,但我无法从标准中获得完整的证据.
我已经发现了什么(感谢npw):
来自[ expr.call#5 ]:
如果参数是const引用类型,则在需要时引入临时对象([dcl.type],[lex.literal],[lex.string],[dcl.array],[class.temporary])
前四个引用不适用于我的情况,但第五个给出了希望.
所以我的问题是:标准是否给予保证,那个断言foo是否会被搁置.
在第一个代码示例中,&::i == &i条件始终为true.类型的引用const int&直接绑定到类型的对象const int.没有创建临时对象.
C++ 14 [dcl.init.ref]/5:
对类型"cv1 T1"的引用由类型"cv2 T2"的表达式初始化,如下所示:
- 如果引用是左值引用和初始化表达式
- 是左值(但不是位域),"cv1 T1"与"cv2 T2"引用兼容,或者
- [...],然后在第一种情况下将引用绑定到初始化表达式lvalue [...]
类型与其自身是引用兼容的.
第二个例子是类似的:当然,用对象的地址初始化一个指针不会创建一个临时的.它指向对象.