当一个引用被另一个延长临时生命周期的引用初始化时,这个新引用不会扩展任何东西。
但是当强制 RVO 阻止引用被复制时会发生什么?
考虑这个例子: run on gcc.godbolt.org
#include <iostream>
struct A
{
A() {std::cout << "A()\n";}
A(const A &) = delete;
A &operator=(const A &) = delete;
~A() {std::cout << "~A()\n";}
};
struct B
{
const A &a;
};
struct C
{
B b;
};
int main()
{
[[maybe_unused]] C c{ B{ A{} } };
std::cout << "---\n";
}
Run Code Online (Sandbox Code Playgroud)
在 GCC 下打印
A()
---
~A()
Run Code Online (Sandbox Code Playgroud)
但在 Clang 下,结果是
A()
~A()
---
Run Code Online (Sandbox Code Playgroud)
哪个编译器是正确的?
乍一看,GCC 做对了。但在这个例子中:
C foo()
{
return { …Run Code Online (Sandbox Code Playgroud) 我试图理解 C++ 中的生命周期延长保证。有人可以解释为什么下面不同类型括号的使用在调用临时对象析构函数时会产生不同的结果吗?
#include <iostream>
struct X {
X() {
std::cout << __PRETTY_FUNCTION__ <<"\n";
}
~X() {
std::cout << __PRETTY_FUNCTION__ <<"\n";
}
};
struct Y {
X &&y;
};
int main() {
Y y1(X{});
std::cout << "Here1\n";
Y y2{X{}};
std::cout << "Here2\n";
}
Run Code Online (Sandbox Code Playgroud)
输出
X::X()
X::~X()
Here1
X::X()
Here2
X::~X()
Run Code Online (Sandbox Code Playgroud)