简体   繁体   English

通过将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>&

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 as std::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的生命周期。

不匹配调用 '(const Y) (int&amp;, std::mersenne_twister_engine <long unsigned int,< div><div id="text_translate"><p> 有我的.hpp:</p><pre> #include &lt;random&gt; #include &lt;ctime&gt; #include &lt;cmath&gt; #ifndef RECUIT_HPP #define RECUIT_HPP template &lt; class E, class Func, class TempSeq, class RandomY, class RNG&gt; E recuit_simule(const Func &amp; phi, E x0, const TempSeq &amp; T, const RandomY &amp; Y, RNG &amp; G, long unsigned N) { std::uniform_real_distribution&lt;double&gt; U(0,1); E y; double u; for(int i=0; i&lt;N; i++) { y=Y(x0, G); u=U(G); if(u &lt;= fmin(1, exp((phi(x0) - phi(y))/T(N)))) { x0=y; } } return x0; } #endif</pre><p> 和我的.cpp:</p><pre> #include "recuit.hpp" #include &lt;iostream&gt; class Y { private: std::normal_distribution&lt;double&gt; N; public: Y(): N(0,1) {} double operator()(const double &amp; x, std::mt19937 &amp; G) { return x + N(G); } }; int main() { auto phi=[](const double &amp; x) { return x*x*x*x*x*x - 48*x*x; }; auto T=[] (long unsigned n) { return 10 * pow(0.9, n); }; YA; std::mt19937 G; double x = recuit_simule(phi, 0, T, A, G, 1000); std::cout &lt;&lt; x &lt;&lt; std::endl; return 0; }</pre><p> 当我编译 my.cpp 时,my.hpp 中有以下错误:</p><blockquote><p> recuit.hpp:17:6: 错误: 不匹配调用 '(const Y) (int&amp;, std::mersenne_twister_engine&amp;)'</p></blockquote><p> 对于该行:</p><pre> y=Y(x0, G);</pre><p> 我不明白为什么</p></div></long> - no match for call to ‘(const Y) (int&, std::mersenne_twister_engine<long unsigned int,

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 分配std :: function <int(int)> 到std :: function <const int&(const int& x)> - Assigning std::function<int(int)> to std::function<const int&(const int& x)> 将const int和vs int分配给const int& - Assigning double to const int& vs int to const int& 没有匹配的函数来调用&#39;std :: less <int> :: less(const int&,const int&)&#39; - No matching function for call to ‘std::less<int>::less(const int&, const int&)’ 什么是`std :: tuple <int [N]>`的用法? - What's the use of `std::tuple<int[N]>`? 如何获取指向std :: get &lt;0,tuple的指针 <int,int> &gt;)? - How to get a pointer to std::get<0,tuple<int,int>>)? 有没有办法将 std::get(std::tuple) 与非常量 int 作为模板参数一起使用? - Is there a way to use std::get(std::tuple) with a non-const int as template argument? 带有模板推导,std :: vector <int&> 可行吗? - With template deduction, std::vector<int&> is feasible? std :: function的sizeof <void(int&)> 类型 - Sizeof of std::function<void(int&)> type 不匹配调用 '(const Y) (int&amp;, std::mersenne_twister_engine <long unsigned int,< div><div id="text_translate"><p> 有我的.hpp:</p><pre> #include &lt;random&gt; #include &lt;ctime&gt; #include &lt;cmath&gt; #ifndef RECUIT_HPP #define RECUIT_HPP template &lt; class E, class Func, class TempSeq, class RandomY, class RNG&gt; E recuit_simule(const Func &amp; phi, E x0, const TempSeq &amp; T, const RandomY &amp; Y, RNG &amp; G, long unsigned N) { std::uniform_real_distribution&lt;double&gt; U(0,1); E y; double u; for(int i=0; i&lt;N; i++) { y=Y(x0, G); u=U(G); if(u &lt;= fmin(1, exp((phi(x0) - phi(y))/T(N)))) { x0=y; } } return x0; } #endif</pre><p> 和我的.cpp:</p><pre> #include "recuit.hpp" #include &lt;iostream&gt; class Y { private: std::normal_distribution&lt;double&gt; N; public: Y(): N(0,1) {} double operator()(const double &amp; x, std::mt19937 &amp; G) { return x + N(G); } }; int main() { auto phi=[](const double &amp; x) { return x*x*x*x*x*x - 48*x*x; }; auto T=[] (long unsigned n) { return 10 * pow(0.9, n); }; YA; std::mt19937 G; double x = recuit_simule(phi, 0, T, A, G, 1000); std::cout &lt;&lt; x &lt;&lt; std::endl; return 0; }</pre><p> 当我编译 my.cpp 时,my.hpp 中有以下错误:</p><blockquote><p> recuit.hpp:17:6: 错误: 不匹配调用 '(const Y) (int&amp;, std::mersenne_twister_engine&amp;)'</p></blockquote><p> 对于该行:</p><pre> y=Y(x0, G);</pre><p> 我不明白为什么</p></div></long> - no match for call to ‘(const Y) (int&, std::mersenne_twister_engine<long unsigned int, &#39;运算符&lt;&lt;(std :: ostream&,int&)&#39;不明确 - 'operator<<(std::ostream&, int&)’ is ambiguous
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM