c++ - 类型不可知的抽象以使用相同的运行时接口处理正向和反向迭代器和范围?
问题描述
通过设计正向和反向迭代器和范围是根本不同的类型。这在它允许的编译时优化中很好。有时最好将类型差异隐藏在允许将它们传递到相同运行时接口的抽象后面。
是否有任何适配器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
type 擦除迭代对象类型并仅公开输出类型和迭代器访问类型。
请注意,此处的类型擦除需要通过虚函数调用以取消引用迭代器,因此存在性能成本,但只要在循环内执行非平凡操作,此成本可能无关紧要。
BUG 警告: 在 ~ ish 到发布(2020-08)boost::range
之间有一个大错误,这将导致访问被破坏的项目,这将导致 UB(未定义的行为/可能崩溃)解决此问题的方法存在于下面的代码中通过模板参数显式传递所谓的引用类型,这会导致一些内部机制避免出错。1.55
1.74
any_range
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;
}
推荐阅读
- leaflet - Leaflet mapbox.dark 主题不起作用,如何获得深色主题
- java - Android Java,setOnTouchListener 每 0.25 秒从字符串中删除 1 个最后一个字符
- database - 如何通过互联网连接到托管在 raspberry 上的 mariadb 数据库?
- reactjs - 错误 400:使用 http://localhost:3000 时的 redirect_uri_mismatch
- google-cloud-platform - 无法 ping 位于同一 VPC 中的不同子网中的虚拟机
- c++ - 为什么我的断言不会引发错误?
- c++ - 为什么 MSVC 和 GCC 在 vtable 中以不同方式放置覆盖的纯虚函数?
- unix - Bash Unix:Tee 和 PID
- python-3.x - django 模型在每次迁移时都会收到 Alter Field 警报
- flutter - Get.to(MyPage()) - 如何删除所有以前的路由 - Flutter GetX