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

  • A+
Category:Languages

I was using the std::tuple class and found something I would say is rather unexpected behavior.

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. 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>.

 


This is not UB.

but as far as I know std::tuple<int&, int> is not the same type as std::tuple<int, int>.

Yes, and reference can't bind to object with different type directly. Given 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>. Then the temporary is bound to t and gets lifetime extended to the lifetime of t.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: