类型不可知的抽象以使用相同的运行时接口处理正向和反向迭代器和范围?
Type agnostic abstraction to handle forward and reverse iterators and ranges using the same runtime interface?
根据设计,正向和反向迭代器和范围是根本不同的类型。这在它允许的编译时优化中很好。有时,最好将类型差异隐藏在允许将它们传递到同一运行时接口的抽象后面。
boost
或stl
中是否有任何适配器使这变得容易?(理想但不严格C++11(
以下代码显示已知/预期的故障和所需的假设:
#include <boost/range.hpp>
#include <vector>
using Ints = std::vector<int>;
void real(boost::iterator_range<Ints::iterator> range){}
void fake(boost::agnostic_range<Ints::iterator> range){} // imaginary desired
int main()
{
auto ints = Ints{1,2,3,4,5};
real(boost::make_iterator_range(ints.begin(), ints.end()));
real(boost::make_iterator_range(ints.rbegin(), ints.rend())); // Error
fake(boost::make_agnsotic_range(ints.begin(), ints.end())); // imaginary
fake(boost::make_agnsotic_range(ints.rbegin(), ints.rend())); // imaginary
return 0;
}
是的! Boost::any_range
类型擦除迭代对象类型,并仅公开输出类型和迭代器访问类型。
请注意,此处的类型擦除需要通过虚函数调用来取消引用迭代器,因此存在性能成本,但只要在循环内执行非平凡操作,此成本就可能无关紧要。
错误警告:boost::range
在发布1.74
(2020-08(之前1.55
~之间有一个大错误,这将导致访问被破坏的项目通过any_range
,从而导致UB(未定义的行为/可能崩溃( 解决此问题的方法存在于下面的代码中,您通过模板参数显式传递所谓的引用类型作为const
,这会导致某些内部机制避免因错误而跳闸。
#include <boost/range/adaptor/type_erased.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/range/any_range.hpp>
#include <vector>
#include <list>
#include <iostream>
// note const int bug workaround
using GenericBiDirIntRange =
boost::any_range<int, boost::bidirectional_traversal_tag, const int>;
void possible(GenericBiDirIntRange const &inputRange) {
for(auto item: inputRange)
std::cout << item << "n";
}
// note const int bug workaround
using type_erased_bi =
boost::adaptors::type_erased<int, boost::bidirectional_traversal_tag, const int>;
using reversed = boost::adaptors::reversed;
auto main() -> int {
auto intVec = std::vector<int>{1, 2, 3, 4};
auto intList = std::list<int>{1, 2, 3, 4};
possible(intVec | type_erased_bi());
possible(intList | reversed | type_erased_bi());
return 0;
}
相关文章:
- 在C++程序中使用的迭代器中未处理的异常
- std::remove() 按预期处理文字,但不能与取消引用的迭代器一起工作
- 类型不可知的抽象以使用相同的运行时接口处理正向和反向迭代器和范围?
- 如何 safley 处理循环中的迭代器
- 自定义迭代器:如果 a 和 b 的行为不同,如何正确处理距离计算和相等比较
- 处理文件行流迭代器
- 如何处理迭代器::d ifference_type,当你无法测量差异时
- 异常处理.一个人如何抛出迭代器
- STL 是否包含处理数组的迭代器
- 如何使用STL迭代器和reverse_iterator处理数据
- 如何使用 STL 迭代器处理结构
- 为什么在达到容量后在向量中插入时,C++不处理迭代器?
- 在SFML 2.0中使用迭代器处理列表之间的冲突
- 如何在不将代码放入头文件的情况下处理任何迭代器
- 通过引用、指针或迭代器处理对象的函子
- 如何处理多个迭代器类型
- 使用Boost Filter迭代器处理非基元对象
- 标准如何处理容器插入函数中的自引用迭代器?
- erase删除迭代器所指向的元素失败时的处理方法
- 在处理迭代器时被信号SIGSEGV(地址边界错误)终止