unique_ptr 向量的取消引用包装器?
Dereference wrapper for vector of unique_ptr?
我最近遇到了这个article;它提供了 boost 的 indirect_iterator
的基本实现,但用于 unique_ptr
迭代器。我决定稍微调整一下文章中的示例,以便我可以将它用于 class 成员之外的向量:
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))
它根本不起作用。我确实在 Node<T>
class 中提供了 operator<()
的实现,但由于某些原因我的代码无法编译。我得到的编译错误非常广泛且难以阅读,但是,我设法提取了我认为导致问题的内容:
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_type
、BaseIterator::pointer
和 BaseIterator::reference
,它们与 [=24] 不匹配=] 你的 operator
类型。
正确的实现应该更像是
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;
};
我最近遇到了这个article;它提供了 boost 的 indirect_iterator
的基本实现,但用于 unique_ptr
迭代器。我决定稍微调整一下文章中的示例,以便我可以将它用于 class 成员之外的向量:
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))
它根本不起作用。我确实在 Node<T>
class 中提供了 operator<()
的实现,但由于某些原因我的代码无法编译。我得到的编译错误非常广泛且难以阅读,但是,我设法提取了我认为导致问题的内容:
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
,它们与 [=24] 不匹配=] 你的 operator
类型。
正确的实现应该更像是
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;
};