gpt4 book ai didi

c++ - boost function_input_iterator 范围的快捷语法

转载 作者:搜寻专家 更新时间:2023-10-31 00:57:22 24 4
gpt4 key购买 nike

我想知道是否有这种代码的快捷语法:

#include <boost/iterator/function_input_iterator.hpp>
#include <boost/range.hpp>

int main() {
std::function<int (int)> f = [](int i) -> int {
// some logic, return int
};
auto r = boost::make_iterator_range(boost::make_function_input_iterator(f, 0), boost::make_function_input_iterator(f, 10));
return 0;
}

两个注意事项:

  • 我无法使用 auto f = [](int i) ->int {...};因为这会导致:

error: no type named 'result_type' in 'struct main()::<lambda(int)>'

出于某种原因使用 std::function 修复了它。

  • 我也不能通过 f作为临时内联即 boost::make_function_input_iterator([](int i) ->int {...}, ...因为该函数通过引用获取 f。

理想情况下,我希望能够做到:

make_function_input_range(0, 10, [](int i)->int {...});

最佳答案

您可以使用添加 typedef 的普通包装器:

template <typename F>
struct ref_wrap : std::reference_wrapper<F> {
typedef decltype(std::declval<F>()() result_type;
ref_wrap(F& f) : std::reference_wrapper<F>(f) {}
};

PS. I use a reference wrapper to stay with function_input_iterator's requirements, which already require the function to be an lvalue reference. You could leave this behind now, actually, since we return the function wrapper as well as the range, see below

接下来,有一个帮助程序返回该包装器的元组和构建在其上的迭代器范围:

template <typename F>
struct input_function_range_wrapper {
struct ref_wrap : std::reference_wrapper<F> {
typedef decltype(std::declval<F>()()) result_type;
ref_wrap(F& f) : std::reference_wrapper<F>(f) {}
} wrap;

using It = boost::function_input_iterator<ref_wrap, int>;
boost::iterator_range<It> range;

template <typename V>
input_function_range_wrapper(F& f, V a, V b) : wrap(f), range(It(wrap, a), It(wrap, b))
{ }
};

为了方便使用,让我们将它移到 detail 命名空间并添加一个工厂函数:

template <typename F, typename V = int>
auto make_input_function_range(F& f, V a, V b) {
return detail::input_function_range_wrapper<F>(f, a, b);
}

现在最重要的是,我们添加启用 ADL 的 beginend 调用以及 PRONTO,我们可以在其上使用 c++ 的 ranged-for:

int main() {
auto f = [i=1]() mutable { return i*=2; };

for (auto v : make_input_function_range(f, 0, 10)) {
std::cout << v << " ";
}
}

打印

2 4 8 16 32 64 128 256 512 1024 

完整演示

Live On Coliru

#include <boost/iterator/function_input_iterator.hpp>
#include <boost/range.hpp>

namespace detail {

template <typename F>
struct input_function_range_wrapper {
struct ref_wrap : std::reference_wrapper<F> {
typedef decltype(std::declval<F>()(/*std::declval<V>()*/)) result_type;
ref_wrap(F& f) : std::reference_wrapper<F>(f) {}
} wrap;

using It = boost::function_input_iterator<ref_wrap, int>;
boost::iterator_range<It> range;

template <typename V>
input_function_range_wrapper(F& f, V a, V b) : wrap(f), range(It(wrap, a), It(wrap, b))
{ }
};

template <typename... Ts>
auto begin(input_function_range_wrapper<Ts...>& r) { return r.range.begin(); }
template <typename ... Ts>
auto begin(input_function_range_wrapper<Ts...> const& r) { return r.range.begin(); }
template <typename ... Ts>
auto end (input_function_range_wrapper<Ts...>& r) { return r.range.end (); }
template <typename ... Ts>
auto end (input_function_range_wrapper<Ts...> const& r) { return r.range.end (); }
}

template <typename F, typename V = int>
auto make_input_function_range(F& f, V a, V b) {
return detail::input_function_range_wrapper<F>(f, a, b);
}

#include <iostream>

int main() {
auto f = [i=1]() mutable { return i*=2; };

for (auto v : make_input_function_range(f, 0, 10)) {
std::cout << v << " ";
}
}

关于c++ - boost function_input_iterator 范围的快捷语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37607970/

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