c++11 - unique_ptr 向量的取消引用包装器?

标签 c++11 vector iterator wrapper unique-ptr

我最近遇到了这个article ;它提供了 boost 的基本实现 indirect_iterator但对于unique_ptr迭代器。我决定稍微调整一下文章中的示例,以便我可以将其用于类成员之外的向量:

template <typename T>
using SPN = std::unique_ptr<Node<T>>;

template <class BaseIterator>
struct DReferenceIterator : BaseIterator
{
  explicit DReferenceIterator(const BaseIterator & other) : BaseIterator(other) {}
  auto & operator*() const { return *(this->BaseIterator::operator*()); }
  auto * operator->() const { return this->BaseIterator::operator*().get(); }
  auto & operator[](size_t n) const { return *(this->BaseIterator::operator[](n)); }
};

template<typename T>
auto begin_t(std::vector<SPN<T>> & v) 
{
  return DReferenceIterator<typename std::vector<SPN<T>>::iterator>(v.begin());
}

template<typename T>
auto end_t(std::vector<SPN<T>> & v) 
{
  return DReferenceIterator<typename std::vector<SPN<T>>::iterator>(v.end());
}

我可以使用std::find(begin_t(v), end_t(v), value)完全没有问题。但是,如果我尝试调用 std::sort(begin_t(v), end_t(v))它根本不起作用。我确实提供了 operator<() 的实现在 Node<T>类,但由于某种原因我的代码无法编译。我得到的编译错误非常广泛且难以阅读,但是,我设法提取了一些我认为导致问题的内容:

binary =: no operator found which takes a right-hand operand of type std::unique_ptr<Node<float>,std::default_delete<_Ty>> (or there is no acceptable conversion)

此消息是否意味着 std::sort()正在尝试复制unique_ptr ?在这种情况下,这是否意味着 DReferenceIterator包装器未按预期工作?我对 C++ 还很陌生,所以如果不是这种情况,请帮助我了解问题到底是什么。

最佳答案

您的DReferenceIterator在暴露内容方面向标准库撒谎。这会导致您在尝试std::sort 时看到错误。

通过从 BaseIterator 派生,您将继承以下(其中包括)BaseIterator::value_typeBaseIterator::pointerBaseIterator::reference,与您的运算符的返回类型不匹配。

正确的实现更像是

template <class BaseIterator>
struct DReferenceIterator
{
  using value_type = BaseIterator::value_type::element_type;
  using reference = value_type &;
  using pointer = value_type *;
  using difference_type = BaseIterator::difference_type
  using iterator_category = BaseIterator::iterator_category;

  explicit DReferenceIterator(const BaseIterator & other) : other(other) {}

  reference operator*() const { return **other; }
  pointer   operator->() const { return (*other).get(); }
  reference operator[](size_t n) const { return (*other)[n]; }

  DReferenceIterator& operator++() { ++other; return *this; }
  DReferenceIterator& operator--() { --other; return *this; }

  DReferenceIterator& operator+=(difference_type n) { other += n; return *this; }
  DReferenceIterator& operator-=(difference_type n) { other -= n; return *this; }
  difference_type operator-(DReferenceIterator& rhs) { return other - rhs.other; }
  bool operator<(DReferenceIterator& rhs) { return other < rhs.other; }

  // And all the other operators, in terms of those      

private: 
  BaseIterator other;
};

关于c++11 - unique_ptr 向量的取消引用包装器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48191770/

相关文章:

c++ - -1、+1 的所有组合的 vector 的 vector

c++ - 将对象插入 vector 然后将 vector 插入堆时堆无效

java - 使用迭代器的 ArrayList 的不同值的 ArrayList

c++ - 如何使用 C++ 避免其中包含 "for"条件的 "if"循环?

c++ - 为什么 std::atomic_compare_exchange 更新期望值?

c++ - unique_ptr 是否保证在 move 后存储 nullptr?

c++ - 在iso 8601时间戳c++之前和之后获取设定时间

C++在 vector 迭代中删除并返回指向对象的指针

java - 哪个类实现了迭代器的 Next() 方法?

c++ - 在 C++ 中使用集合迭代器