如何为Hana序列写一个for循环?

编程入门 行业动态 更新时间:2024-10-14 14:19:15
本文介绍了如何为Hana序列写一个for循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个Boos.Hana序列,我想打印它到屏幕,用逗号分隔。但是逗号只分开元素,所以我必须检查我是否在最后一个元素。

目前我的黑客是非常糟糕的(看着指针,并转换到 void * 。

template< class P,class ... Ts> decltype(auto)operator<<( std :: ostream& os, boost :: hana :: tuple< Ts ...> const& tpl ){ os<<{; boost: :hana :: for_each( tpl,[& x] { os<< x; if((void *)&boost; hana: :back(tpl)!=(void *)& x)os<<,; } ); return os< b $ b}

在Boost.Fusion的情况下,它更复杂,因为我使用融合迭代器 boost :: fusion :: begin 和 boost :: fusion :: end ),但至少我可以比较迭代器。( bool last = result_of :: equal_to< typename result_of :: next< First> :: type,Last> :: value )。

另一种提出这个问题的方法是如果在Hana中有(meta)迭代器。

解决方案

,为了回答你的意见, drop_back 确实做了一个副本。 Hana中的所有算法都制作副本,并且渴望,如此处所述。 p>

其次,您可以使用 hana :: intersperse 在每个元素之间添加逗号,导致类似

template< class P,class ... Ts> decltype(auto)operator<<( std :: ostream& os, boost :: hana :: tuple< Ts ...> const& tpl ) { os<< {; boost :: hana :: for_each(boost :: hana :: intersperse(tpl,,), [&](auto const& x){ os< ; x; }); return os<< };然而,最好的解决方案可能是使用 }

< experimental :: print ,这完全符合您的需求:

#include< boost / hana /experimental/printable.hpp> #include< boost / hana / tuple.hpp> #include< iostream> int main(){ auto ts = hana :: make_tuple(1,2,3); std :: cout<< hana :: experimental :: print(ts); }

/ strong>

如果要使用 intersperse 解决方案,但不想复制可以执行以下操作:

#include< boost / hana.hpp> #include< functional> #include< iostream> namespace hana = boost :: hana; template< class ... Ts> decltype(auto)operator<<(std :: ostream& os,hana :: tuple< Ts ...> const& tpl){ os& {; char const * sep =,; auto refs = hana :: transform(tpl,[](auto const& t){return std :: ref(t);}); hana :: for_each(hana :: intersperse(refs,std :: ref(sep)), [&](auto const& x){ os<< x .get(); }); return os<< }; }

但实际上你应该使用 hana: :experimental :: print 。如果你的用例是性能关键的,你想避免创建一个 std :: string ,我会质疑 std :: ostream 。

编辑结束

I have a Boos.Hana sequence and I would like to print it to screen separated by commas. However the commas separate elements only, so I have to check if I am at the last element.

Currently my hack is pretty bad (looking at the pointer and casting to void*.

template<class P, class... Ts> decltype(auto) operator<<( std::ostream& os, boost::hana::tuple<Ts...> const& tpl ){ os << "{"; boost::hana::for_each( tpl, [&](auto& x){ os << x; if((void*)&boost::hana::back(tpl) != (void*)&x) os << ", "; } ); return os << "}"; }

In the case of Boost.Fusion it was more complicated because I use fusion iterators (boost::fusion::begin and boost::fusion::end) but at least I could compare the iterators. (bool last = result_of::equal_to<typename result_of::next<First>::type, Last>::value).

Another way to ask this question is if there are (meta) iterators in Hana.

解决方案

First, to answer your comment, drop_back does make a copy. All algorithms in Hana make copies and are eager, as documented here.

Secondly, you could use hana::intersperse to add a comma between each element, resulting in something like

template<class P, class... Ts> decltype(auto) operator<<( std::ostream& os, boost::hana::tuple<Ts...> const& tpl ){ os << "{"; boost::hana::for_each(boost::hana::intersperse(tpl, ", "), [&](auto const& x){ os << x; }); return os << "}"; }

However, the best solution would probably be to use experimental::print, which does exactly what you want:

#include <boost/hana/experimental/printable.hpp> #include <boost/hana/tuple.hpp> #include <iostream> int main() { auto ts = hana::make_tuple(1, 2, 3); std::cout << hana::experimental::print(ts); }

Edit

If you want to use the intersperse solution, but do not want to make a copy of the sequence, you can do the following:

#include <boost/hana.hpp> #include <functional> #include <iostream> namespace hana = boost::hana; template <class... Ts> decltype(auto) operator<<(std::ostream& os, hana::tuple<Ts...> const& tpl) { os << "{"; char const* sep = ", "; auto refs = hana::transform(tpl, [](auto const& t) { return std::ref(t); }); hana::for_each(hana::intersperse(refs, std::ref(sep)), [&](auto const& x){ os << x.get(); }); return os << "}"; }

But really, you should probably be using hana::experimental::print. And if your use case is performance critical and you want to avoid creating a std::string, I would question the usage of std::ostream in the first place.

End of edit

更多推荐

如何为Hana序列写一个for循环?

本文发布于:2023-10-23 05:22:45,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1519913.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:序列   何为   Hana

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!