加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 在Boost :: range中组合适配器

发布时间:2020-12-16 05:44:32 所属栏目:百科 来源:网络整理
导读:我开始玩Boost :: Range,以便有一个 pipeline of lazy transforms in C++.我现在的问题是如何拆分较小部分的管道.假设我有: int main(){ auto map = boost::adaptors::transformed; // shorten the name auto sink = generate(1) | map([](int x){ return 2
我开始玩Boost :: Range,以便有一个 pipeline of lazy transforms in C++.我现在的问题是如何拆分较小部分的管道.假设我有:
int main(){
  auto map = boost::adaptors::transformed; // shorten the name
  auto sink = generate(1) | map([](int x){ return 2*x; })
                          | map([](int x){ return x+1; })
                          | map([](int x){ return 3*x; });
  for(auto i : sink)
    std::cout << i << "n";
}

我想用magic_transform替换前两个地图,即:

int main(){
  auto map = boost::adaptors::transformed; // shorten the name
  auto sink = generate(1) | magic_transform()
                          | map([](int x){ return 3*x; });
  for(auto i : sink)
    std::cout << i << "n";
}

怎么会写magic_transform?我抬头看了Boost::Range’s documentation,但是我不能很好的把握.

附录:我正在寻找一个这样写的类:

class magic_transform {
    ... run_pipeline(... input) {
        return input | map([](int x){ return 2*x; })
                     | map([](int x){ return x+1; });
};

解决方法

最困难的问题是在代码中找出返回类型. decltype和lambdas不能很好地混合( see here),所以我们必须考虑一种替代方法:
auto map = boost::adaptors::transformed;

namespace magic_transform
{
   std::function<int(int)> f1 = [](int x){ return 2*x; };
   std::function<int(int)> f2 = [](int x){ return x+1; };
   template <typename Range>
   auto run_pipeline(Range input) -> decltype(input | map(f1) | map(f1))
   {
        return input | map(f1) | map(f2);
   }
}

...
auto sink = magic_transform::run_pipeline(generate(1))
                          | map([](int x){ return 3*x; });

简单的解决方案是将lambdas粘贴到std ::函数中,因此我们可以使用decltype来推断返回类型.我在这个例子中使用了namespace magic_transform,但是如果你也愿意,你可以将这段代码修改成一个类. Here is a link使您的代码适应上述.

此外,使用std ::函数可能会在这里过度使用.相反,您可以只声明两个正常的功能(example).

我也在尝试boost :: any_range,似乎有一些不兼容的C 11羊羔等.最接近的是以下(example):

auto map = boost::adaptors::transformed;
using range = boost::any_range<
               const int,boost::forward_traversal_tag,const int&,std::ptrdiff_t
               >;

namespace magic_transform
{
    template <typename Range>
    range run_pipeline(Range r)
    {
        return r | map(std::function<int(int)>([](int x){ return 2*x; }))
             | map(std::function<int(int)>([](int x){ return x+1; }));
    }
}

int main(){
  auto sink = magic_transform::run_pipeline(boost::irange(0,10))
                          | map([](int x){ return 3*x; });
  for(auto i : sink)
    std::cout << i << "n";
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读