具体来说,是以下合法的C++?
class A{}; void foo(A*); void bar(const A&); int main(void) { foo(&A()); // 1 bar(A()); // 2 }
它似乎工作正常,但这并不意味着它必然是合法的.是吗?
编辑 - 更改A&
为const A&
1:不允许使用临时地址.Visual C++允许它作为语言扩展(默认情况下语言扩展是打开的).
2:这是完全合法的.
不,将非const引用传递给临时对象是违反标准的.您可以使用const引用:
class A{}; void bar(const A&); int main(void) { bar(A()); // 2 }
因此,虽然一些编译器会接受它,并且只要在分号后不使用内存就可以工作,但是符合标准的编译器不会接受它.
完全符合标准的C++中不允许使用foo,而bar是可以的.虽然可能性很大,但是foo会在发出警告的情况下进行编译,并且bar可能也可能不会编译并发出警告.
A()创建一个临时对象,除非绑定到引用(如bar中的情况),或用于初始化命名对象,否则在创建它的完整表达式的末尾销毁.创建用于保存引用初始值设定项的临时值会持续到其引用范围的末尾.对于bar的情况,这是函数调用,因此您可以完全安全地使用A inside bar.禁止将临时对象(这是一个右值)绑定到非const引用.同样禁止使用rvalue的地址(作为参数传递给foo初始化A).