【问题标题】:Why are there const overloads of mutating Boost.Range algorithms?为什么变异 Boost.Range 算法存在 const 重载?
【发布时间】:2017-10-31 02:09:05
【问题描述】:

Boost.Range 的文档(和实现)显示了以 const refs 作为参数的变异算法的重载。例如Boost.Range's Sort documentation 显示:

template<class RandomAccessRange>
RandomAccessRange& sort(RandomAccessRange& rng);

template<class RandomAccessRange>
const RandomAccessRange& sort(const RandomAccessRange& rng);

template<class RandomAccessRange, class BinaryPredicate>
RandomAccessRange& sort(RandomAccessRange& rng, BinaryPredicate pred);

template<class RandomAccessRange, class BinaryPredicate>
const RandomAccessRange& sort(const RandomAccessRange& rng, BinaryPredicate pred);

重载 2 和 4 的意义何在?当然,能够通过临时人员很好,但是const&amp; 使这一点变得毫无意义。 Rvalue-references 将是最受欢迎的,但我的理解是它们对 Boost.Range 的支持过于侵入性,并且“推迟”到 Range.V3 的采用(如果同时它是 Boost 的一部分,那就太好了)。

【问题讨论】:

  • 从源代码来看,它似乎是针对const 的容器,因为容器的状态不能被修改,但底层元素可以被改变,
  • const iterator_pair&lt;It, It&gt; 是一个常量范围,但这并不意味着目标元素无法排序...

标签: c++ c++11 boost c++14 range-v3


【解决方案1】:
template<class T>
struct span_t {
  T* b =0;
  T* e =0;
  T* begin() const { return b; }
  T* end() const { return e; }
  std::size_t size() const { return end()-begin(); }
  bool empty() const { return size()==0; }
  T& operator[](std::size_t i) const { return b[i]; }
  span_t()=default;
  span_t(span_t const&)=default;
  span_t& operator=(span_t const&)=default;
  span_t( T* s, T* f ):b(s),e(f) {}
  span_t( T* s, std::size_t l):span_t(s, s+l) {}
};

这是一个(实用且有用的)随机访问范围。

它的所有方法(operator= 除外)都是const。您可以对其进行排序。

并非所有范围都将const 从范围传播到范围中的元素。

【讨论】:

  • 感谢具体示例。但是:拥有这样一个容器真的有意义吗?那么声明const 有什么好处呢?
  • @akim 那不是容器;这是一个范围视图。 span 非常有用。就像使用原始 C 数组或缓冲区指针很有用一样,span 将其升级为现代 C++。它允许您在缓冲区中传递范围,而无需复制缓冲区或关心缓冲区的确切分配方式。它为您提供具有大量语法糖的裸机性能。它是const,因为它的值只是相关范围的跨度,而不是范围的内容,就像 const 指针和指向 const 的指针是不同的。跨度的副本不会复制元素,例如指针。
猜你喜欢
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-22
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
相关资源
最近更新 更多