如何写一个for循环的花序列? [英] How to write a for loop for a Hana sequence?

查看:180
本文介绍了如何写一个for循环的花序列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Boos.Hana序列和我想打印屏幕用逗号分隔。然而,逗号分隔的元素而已,所以我要检查,如果我在最后一个元素。

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.

目前我劈为pretty坏(看着指针,铸造无效*

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 << "}";
}

在Boost.Fusion的情况下,它是更为复杂,因为我使用的融合迭代器(的boost ::融合::开始的boost ::融合::结束),但至少我可以比较的迭代器。 (布尔最后=的result_of :: equal_to&LT;类型名的result_of ::接下来的&lt;第一&GT; ::类型,最后&GT; ::值)。

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.

推荐答案

首先,要回答你的评论, drop_back 确实让副本。哈纳所有算法进行复印,并渴望,因为这里记录

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

其次,你可以使用<一个href=\"http://boostorg.github.io/hana/structboost_1_1hana_1_1Sequence.html#ab6e88c5dd3f638a60c0a451ad6db95ec\"相对=nofollow> 花::点缀 增加各元素之间用逗号,导致类似

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);
}


修改

如果你想使用点缀的解决方案,但不想让序列的拷贝,你可以做到以下几点:

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 << "}";
}

不过说真的,你或许应该使用花::实验::打印。如果你的用例是性能的关键,你想避免创建一个的std ::字符串,我会质疑中的std :: ostream的<用法/ code>摆在首位。

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.

修改结束

这篇关于如何写一个for循环的花序列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆