延长 std::tuple<int&,int> 的生命周期,方法是将其分配给 const std::tuple<int, int>&

Extending lifetime of std::tuple<int&,int> by assigning it to const std::tuple<int, int>&

本文关键字:int gt lt std tuple 分配 const 周期 延长 生命 方法      更新时间:2023-10-16

我正在使用std::tuple类,发现一些我会说是相当意外的行为。

考虑代码:

#include <iostream>
#include <tuple>
int i = 20;
std::tuple<int&, int> f() {
    return std::tuple<int&, int>(i, 0);
}
int main() {
    const std::tuple<int, int>& t = f();
    int j = ++i;
    std::cout << std::get<0>(t) << "n";
}

这似乎可以在所有主要编译器上编译和打印20。由于两种类型不同,此标准是否符合或未定义的行为?我知道可以通过将其分配给const T&来延长临时的使用寿命,但据我所知std::tuple<int&, int>std::tuple<int, int>的类型不同。

这是定义良好的行为。

const std::tuple<int, int>& t = f();

没有为您提供对您在f()中创建的元组的引用,因为它们具有不同的类型。 相反,发生的事情是从f()的回归中创建一个临时std::tuple<int, int>,然后这个临时的必然会t。 由于这是一个副本,因此您可以在该时间点获得i的值,并且不再与之耦合。

你用过吗

const std::tuple<int&, int>& t = f();

然后21将被打印出来,因为您仍然可以引用元组中的i

这不是

UB。

但据我所知std::tuple<int&, int>std::tuple<int, int>不是同一类型.

是的,引用不能直接绑定到不同类型的对象。给定const std::tuple<int, int>& t = f();,返回的std::tuple<int&, int>将被隐式转换为std::tuple<int, int>,这是一个临时std::tuple<int, int>。然后临时绑定t,并将生存期延长至t的生存期。