让我们考虑以下程序:
#include <iostream>
#include <tuple>
using namespace std;
const int* f()
{
static int i = 5;
return &i;
}
int main()
{
auto [a] = std::forward_as_tuple( f() );
//auto&& [a] = std::forward_as_tuple( f() ); // same error
//const auto& [a] = std::forward_as_tuple( f() ); // same error
cout << *a << endl;
return 0;
}
我希望它打印5
。我在gcc 13.1和MSVC 19.35上试过,当所有优化都关闭时,它会产生正确的结果。无论如何,当我为gcc添加-O 1或为MSVC添加/O2时,程序在运行时开始崩溃,我几乎无法理解为什么会发生这种情况。我在cppreference上找到了以下Note
:
如果参数是临时参数,forward_as_tuple不会延长它们的生存期;它们必须在完整表达式结束之前使用。
这是解释吗?如果是这样,有人能详细说明我在代码中违反了什么语言规则吗?
1条答案
按热度按时间avwztpqn1#
沿着@NathanOliver留下的线索,我设法在cppreference找到了答案:
函数调用中的引用参数的临时绑定存在,直到包含该函数调用的完整表达式结束:如果函数返回的引用超过了完整表达式的寿命,则它将成为悬空引用。
和
一般来说,临时的生存期不能通过“传递”来进一步延长:从临时对象绑定到的引用变量或数据成员初始化的第二引用不影响其生存期。