[英]Extending lifetime of std::tuple<int&,int> by assigning it to const std::tuple<int, int>&
I was using the std::tuple
class and found something I would say is rather unexpected behavior. 我正在使用
std::tuple
类,发现我会说的是一些意想不到的行为。
Consider the code: 考虑一下代码:
#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";
}
This seems to compile and print 20
on all major compilers. 这似乎在所有主要编译器上编译和打印
20
。 Is this standard conforming, or undefined behavior as the two types are different? 这两种类型的标准是否符合或未定义? I know that one can extend the lifetime of a temporary by assigning it to
const T&
, but as far as I know std::tuple<int&, int>
is not the same type as std::tuple<int, int>
. 我知道可以通过将其赋值给
const T&
来延长临时生命周期,但据我所知std::tuple<int&, int>
与std::tuple<int, int>
。
This is well defined behavior. 这是明确定义的行为。
const std::tuple<int, int>& t = f();
is not giving you a reference to the tuple you created in f()
because they have different types. 没有给你一个你在
f()
创建的元组的引用,因为它们有不同的类型。 Instead what happens is a temporary std::tuple<int, int>
is created from f()
's return and then that temporary is bound to t
. 相反,发生的是临时
std::tuple<int, int>
是从f()
的返回创建的,然后临时绑定到t
。 Since this is a copy you get the value of i
at that point in time and are no longer coupled to it. 由于这是一个副本,因此您可以在该时间点获得
i
的值,并且不再与其耦合。
Had you used 你用过的吗?
const std::tuple<int&, int>& t = f();
then 21
would have been printed since you would still have a reference to i
in the tuple. 然后会打印
21
,因为你仍然会在元组中引用i
。
This is not UB. 这不是UB。
but as far as I know
std::tuple<int&, int>
is not the same type asstd::tuple<int, int>
.但据我所知
std::tuple<int&, int>
与std::tuple<int, int>
。
Yes, and reference can't bind to object with different type directly. 是的,引用不能直接绑定到不同类型的对象。 Given
const std::tuple<int, int>& t = f();
给定
const std::tuple<int, int>& t = f();
, the returned std::tuple<int&, int>
will be converted to std::tuple<int, int>
implicitly, which is a temporary std::tuple<int, int>
. ,返回的
std::tuple<int&, int>
将隐式转换为std::tuple<int, int>
,这是一个临时的std::tuple<int, int>
。 Then the temporary is bound to t
and gets lifetime extended to the lifetime of t
. 然后临时绑定到
t
并将生命周期延长到t
的生命周期。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.