我最近遇到了这个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 typestd::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_type
、BaseIterator::pointer
和 BaseIterator::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/