提升function_input_iterator范围的快捷语法
Shortcut syntax for boost function_input_iterator range
我想知道这种代码是否有快捷方式语法:
#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) {}
};
我使用引用包装器来满足
function_input_iterator
的要求,这已经要求该函数是左值引用。实际上,您现在可以将其抛在脑后,因为我们返回了函数包装器和范围,请参见下文
接下来,有一个帮助程序,它返回该包装器的元组以及基于它构建的迭代器范围:
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 << " ";
}
}
有关error: no type named 'result_type'
,请参阅此错误。
make_function_input_range
编写起来很简单,但由于上述错误,这不能与普通 lambda 一起使用:
template<class T>
auto make_function_input_range(std::size_t begin, std::size_t end, T& f) {
return boost::make_iterator_range(
boost::make_function_input_iterator(f, begin),
boost::make_function_input_iterator(f, end));
}
为了解决这个错误,我会创建一个定义所需result_type
的小帮助程序类型,而不是使用类型擦除std::function
:
template<class T>
struct fun_wrapper {
T f;
using result_type = typename boost::function_types::result_type<T>;
template<class... Args>
result_type operator() (Args&&... args) const {
return f(std::forward<Args>(args)...);
}
};
template<class T>
auto make_fun_wrapper(T&& f) {
return fun_wrapper<T>{std::forward<T>(f)};
}
int main() {
auto wrapped_f = make_fun_wrapper([](int i)->int {/*...*/});
auto range = make_function_input_range(0, 10, wrapped_f);
}
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 助记符和指向成员语法的指针
- 有人能分解一下这个c++模板的语法吗
- C++避免重复声明的语法是什么
- QMetaObject invokeMethod的基于函数指针的语法
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 单独定义模板化嵌套类方法的正确语法
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- 为什么我会收到错误 C2143 语法错误:缺少"*"之前的';'?
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 使用基类指针调用基类的值构造函数的语法是什么?
- 很好的语法来获取对向量/数组数据的大小引用?
- C++语法运算符功能?
- C++使用 rand 定义函数语法
- 在调试模式下引发C++ "deque iterator not dereferencable"异常
- 什么文件可以修改 atom 的C++语法?
- "std::vector:<T>:iterator"模板化函数的C ++正确语法
- 标识符'iterator'的语法错误