首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向量不满足本征3.4中的std::ranges::contiguous_range

向量不满足本征3.4中的std::ranges::contiguous_range
EN

Stack Overflow用户
提问于 2021-12-21 22:13:10
回答 1查看 276关注 0票数 3

为什么Eigen::VectorXd不满足概念std::ranges::contiguous_range?也就是说,static_assert(std::ranges::contiguous_range<Eigen::VectorXd>);不编译。

另外,是否有可能专门化一个模板,使特征向量满足相邻范围的概念?例如,我们可以对std::ranges::enable_borrowed_range进行专门化,使任何范围都满足std::range::borrowed_range概念。换句话说,是否有办法使上述静态断言编译?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-21 22:48:50

必须选择毗连的范围。仅仅通过查看迭代器就无法确定它是连续访问还是随机访问。考虑一下deque<int>::iteratorvector<int>::iterator之间的区别--它们提供了所有相同的操作,返回所有相同的东西,除非vector<int>::iterator明确告诉了您,否则您怎么知道呢?

艾根的迭代器还没有这样做。实际上,在C++20之前,一开始就没有连续迭代器的概念。这是C++20系列的新鲜事。

如果您试图验证它是否是连续的,您可以看到这一点:

代码语言:javascript
复制
using I = Eigen::VectorXd::iterator;
static_assert(std::contiguous_iterator<I>);

gcc的诊断表明:

代码语言:javascript
复制
/opt/compiler-explorer/gcc-trunk-20211221/include/c++/12.0.0/concepts:67:13:   required for the satisfaction of 'derived_from<typename std::__detail::__iter_concept_impl<_Iter>::type, std::contiguous_iterator_tag>' [with _Iter = Eigen::internal::pointer_based_stl_iterator<Eigen::Matrix<double, -1, 1, 0, -1, 1> >]
/opt/compiler-explorer/gcc-trunk-20211221/include/c++/12.0.0/concepts:67:28: note:   'std::contiguous_iterator_tag' is not a base of 'std::random_access_iterator_tag'
   67 |     concept derived_from = __is_base_of(_Base, _Derived)
      |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

基本上,我们的分类是随机访问,而不是连续的。

要正确地做到这一点,特征的方法是添加:

代码语言:javascript
复制
 template<typename XprType>
 class pointer_based_stl_iterator
 {
   enum { is_lvalue  = internal::is_lvalue<XprType>::value };
   typedef pointer_based_stl_iterator<typename internal::remove_const<XprType>::type> non_const_iterator;
   typedef pointer_based_stl_iterator<typename internal::add_const<XprType>::type> const_iterator;
   typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
   // NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
   friend class pointer_based_stl_iterator<typename internal::add_const<XprType>::type>;
   friend class pointer_based_stl_iterator<typename internal::remove_const<XprType>::type>;
 public:
   typedef Index difference_type;
   typedef typename XprType::Scalar value_type;
   typedef std::random_access_iterator_tag iterator_category;
+  typedef std::contiguous_iterator_tag iterator_concept;
   typedef typename internal::conditional<bool(is_lvalue), value_type*, const value_type*>::type pointer;
   typedef typename internal::conditional<bool(is_lvalue), value_type&, const value_type&>::type reference;
};

这将使它成为一个C++20连续迭代器。

或者,您可以自己在外部完成此操作,尽管这不是一个好主意(实际上,应该正确地执行此操作的应该是Eigen ),并且必须比任何范围使用的时间都早:

代码语言:javascript
复制
template <>
struct std::iterator_traits<I> {
    using iterator_concept = std::contiguous_iterator_tag;
    using iterator_category = std::random_access_iterator_tag;
    using value_type = typename I::value_type;
    using difference_type = typename I::difference_type;
};
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70442139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档