c – 使用std :: tie初始化多个引用
发布时间:2020-12-16 03:41:46 所属栏目:百科 来源:网络整理
导读:我想通过std :: tie(或std :: forward_as_tuple)-see玩具代码,通过std :: tuple初始化从函数返回的多个引用. #include tuple#include iostreamclass Foo{public: Foo () : m_memberInt(5),m_anotherMemberInt(7) {} void IncrementMembers() {++m_memberInt;
我想通过std :: tie(或std :: forward_as_tuple)-see玩具代码,通过std :: tuple初始化从函数返回的多个引用.
#include <tuple> #include <iostream> class Foo { public: Foo () : m_memberInt(5),m_anotherMemberInt(7) {} void IncrementMembers() {++m_memberInt; ++m_anotherMemberInt;} std::tuple<int &,int &> GetMembers() {return std::tie(m_memberInt,m_anotherMemberInt);} private: int m_memberInt; int m_anotherMemberInt; }; int main() { Foo foo; // Can't have dangling references. // int &x,&y; // std::tie(x,y) = foo.GetMembers(); std::tuple<int &,int &> tmpTuple = foo.GetMembers(); int &x = std::get<0>(tmpTuple); int &y = std::get<1>(tmpTuple); std::cout << x << " " << y << std::endl; foo.IncrementMembers(); std::cout << x << " " << y << std::endl; return 0; } 上面的解决方案有效,但是临时std :: tuple和多个std :: gets很烦人,如果可能的话,能够避免这种情况会非常好(比如返回非引用时). 问题是我们不能有悬空引用,所以不能事先初始化变量.是否有一些C 11 / C 14的魔法允许我初始化引用,因为我调用std :: tie?或者上面是唯一的解决方案? 解决方法
在C 17中,结构化绑定为您编写代码.
std::tuple<int &,int &> tmpTuple = foo.GetMembers(); int &x = std::get<0>(tmpTuple); int &y = std::get<1>(tmpTuple); 大致相同 auto&[x,y] = foo.GetMembers(); (我的C 17代码中可能有轻微的语法错误,我缺乏经验,但你明白了.) 您可以在C 14中使用延续传递样式和适配器执行类似的操作: template<class Tuple> struct continue_t { Tuple&& tuple; using count = std::tuple_size<std::remove_reference_t<Tuple>>; using indexes = std::make_index_sequence<count{}>; template<std::size_t...Is> auto unpacker(std::index_sequence<Is...>) { return [&](auto&& f)->decltype(auto){ using std::get; // ADL enabled return decltype(f)(f)( get<Is>(std::forward<Tuple>(tuple))... ); }; }; template<class F> decltype(auto) operator->*( F&& f )&& { auto unpack = unpacker( indexes{} ); return unpack( std::forward<F>(f) ); } }; template<class F> continue_t<F> cps( F&& f ) {return {std::forward<F>(f)};} 哪个模数错字,给你: cps(foo.GetMembers()) ->*[&](int& x,int&y) { std::cout << x << " " << y << std::endl; foo.IncrementMembers(); std::cout << x << " " << y << std::endl; }; return 0; 这很奇怪. (注意,cps支持返回对或std :: arrays以及任何“类似tuple”的函数). 实际上没有更好的方法来处理这种结构化绑定,其中有一个原因是添加到C 17. 一个可怕的预处理程序黑客可能写得如下: BIND_VARS( foo.GetMembers(),x,y ); 但是代码量会很大,我所知道的编译器没有让你调试会产生的混乱,你会得到预处理器和C交集引起的所有奇怪的怪癖等等. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |