- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想知道是否有这种代码的快捷语法:
#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 的 begin
和 end
调用以及 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
#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/
我想知道是否有这种代码的快捷语法: #include #include int main() { std::function f = [](int i) -> int { /
我是一名优秀的程序员,十分优秀!