我与一位程序员讨论过,其主要观点是foo
中的以下断言可以传递或不传递,具体取决于编译器。
#include <cassert>
const int i = 0 ;
void foo ( const int& i )
{
assert( &::i == &i ) ;
}
int main ( )
{
foo( i ) ;
}
他告诉我,可以评估(&amp; 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
}
可能这种事情可能发生在某个地方,但不是这种情况。 这就是我的想法,但我无法从标准中获得完整的证据。
我已经找到了(感谢npw):
来自[expr.call#5]:
如果参数是const引用类型,则临时对象是 如果需要引入([dcl.type],[lex.literal],[lex.string], [dcl.array],[class.temporary])
前四个参考文献不适用于我的案例,但第五个参考文献给出了希望。
所以我的问题是:标准是否给予保证,foo
中的断言是否会被搁置。?
答案 0 :(得分:6)
在第一个代码示例中,&::i == &i
条件始终为true。类型const int&
的引用直接绑定到类型const int
的对象。没有创建临时对象。
C ++ 14 [dcl.init.ref] / 5:
对类型“cv1 T1”的引用由类型为“cv2 T2”的表达式初始化,如下所示:
- 如果引用是左值引用和初始化表达式
- 是左值(但不是位字段),“cv1 T1”与“cv2 T2”或
引用兼容- [...], 然后在第一种情况下将引用绑定到初始化表达式lvalue [...]
类型与其自身是引用兼容的。
第二个例子是类似的:当然,用对象的地址初始化一个指针不会创建一个临时的。它指向对象。