gpt4 book ai didi

c++ - 在 Boost::range 中组合适配器

转载 作者:可可西里 更新时间:2023-11-01 15:23:40 25 4
gpt4 key购买 nike

我开始使用 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 替换前两个 map ,即:

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):

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

最佳答案

最困难的问题是找出代码中的返回类型。 decltype 和 lambda 不能很好地混合(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::function 中,这样我们就可以使用 decltype 来推断返回类型。我在示例中使用了命名空间 magic_transform,但如果您也愿意,可以将此代码改编成一个类。 Here is a link根据以上内容调整您的代码。

另外,在这里使用 std::function 可能有点矫枉过正。相反,您可以只声明两个普通函数 ( example )。

我也在试验 boost::any_range,似乎与 C+11 lambda 等不兼容。我能得到的最接近的是以下内容 (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";
}

关于c++ - 在 Boost::range 中组合适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13241740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com