c++ - shared_from_this() 返回 std::shared_ptr<const X>,而不是 std::shared_ptr<X>

标签 c++ c++11 iterator shared-ptr

好吧,这个让我难住了。显然我错过了一些东西,所以我希望有人能告诉我它是什么。

我正在开发一个 C++17 库。我写了一个由 Node 组成的自定义树数据结构对象和自定义迭代器,Node::iterator , 用于遍历树。迭代器看起来像这样:

template <typename T>
class NodeIterator {
public:
    using value_type = T;
    using difference_type = std::ptrdiff_t;
    using pointer = std::shared_ptr<T>;
    using reference = T&;
    using iterator_category = std::forward_iterator_tag;

    NodeIterator() = default;
    NodeIterator(pointer n);

    // Etc.
}

后来……

template class NodeIterator<Node>;
template class NodeIterator<const Node>;

当我将标准迭代器方法( begin()end() 和 const 等价物)添加到父类 Tree 时,我可以控制迭代器的初始值。所以我可以说

Node::iterator Tree::begin() const {
    return Node::iterator(_root);
}

哪里_rootstd::shared_ptr<Node> .这很好用。

但是,我不满足于单独使用这些迭代器方法,我希望在节点本身上使用这些迭代器方法。这样我就可以从任何节点遍历子树,消除 Tree一起上课,然后绕过Node对象。

我声明Node作为

class Node : public std::enable_shared_from_this<Node> {
public:
    using iterator = NodeIterator<Node>;
    using const_iterator = NodeIterator<const Node>;

    iterator begin() const;
    iterator end() const;
    const_iterator cbegin() const;
    const_iterator cend() const;

    // Etc.
}

并将迭代器方法定义为

Node::iterator Node::begin() const {
    return Node::iterator(this->shared_from_this());
}

Node::iterator Node::end() const {
    return Node::iterator(nullptr);
}

Node::const_iterator Node::cbegin() const {
    return Node::const_iterator(this->shared_from_this());
}

Node::const_iterator Node::cend() const {
    return Node::const_iterator(nullptr);
}

然后编译器大声提示 return声明:

src/node.cc:79:9: error: no matching conversion for functional-style cast from
      'shared_ptr<const Node>' to 'Node::iterator' (aka 'NodeIterator<Node>')
        return Node::iterator(this->shared_from_this());
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

及以后...

include/example.h:344:2: note: candidate constructor not viable: no known
      conversion from 'shared_ptr<const Node>' to 'shared_ptr<Node>' for
      1st argument
        NodeIterator(pointer n);
        ^

在另一种方法中,Node::appendChild() , 我自动将父节点 ( std::shared_ptr<Node> ) 设置为 this->shared_from_this() ,而且效果很好。

如果我注释掉 Node::begin()Node::end()并且只使用 cbegin()cend()在我的循环中,它也工作正常。

什么给了?

最佳答案

shared_from_this 有常量和非常量重载。参见 cppreference .在您的 const begin 中,this 是指向 const 的指针并调用 const 重载,该重载将 shared_ptr 返回给 const。

关于c++ - shared_from_this() 返回 std::shared_ptr<const X>,而不是 std::shared_ptr<X>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47361542/

相关文章:

c++ - 有没有办法为 std::map 中小于给定键的第一个元素找到反向迭代器?

c++ - 锁定方案黑客

android - C++ 隐式参数 : this and the returned object, 的顺序哪个先出现?

c++ - 在 Qt 中将一个小部件与另一个小部件交换

c++ - 在基于 for 循环的范围内复制省略

java - 如何在 Java 中修改 PriorityQueue 的元素?

c++ - 如何使用 Boost 内存映射在 C++ 中解析 CSV?

c++ - 我在 C++11 标准中缺少什么?

c++ - C++ 11中的最小和最大可变参数模板变体?

C++ spirit boost : Making a input iterator into a forward iterator