首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >shared_from_this()返回std::shared_ptr<const X>,而不是std::shared_ptr<X>

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

Stack Overflow用户
提问于 2017-11-18 01:25:43
回答 1查看 2.3K关注 0票数 4

好吧,这个让我很困惑。显然我错过了什么,所以我希望有人能告诉我这是什么。

我正在开发一个C++17库。我编写了一个由Node对象和自定义迭代器Node::iterator组成的自定义树数据结构,用于遍历树。迭代器如下所示:

代码语言:javascript
复制
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.
}

后来..。

代码语言:javascript
复制
template class NodeIterator<Node>;
template class NodeIterator<const Node>;

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

代码语言:javascript
复制
Node::iterator Tree::begin() const {
    return Node::iterator(_root);
}

其中_rootstd::shared_ptr<Node>。这个很好用。

然而,不满足于保持足够好的独处,我希望这些迭代器方法在节点本身上。这样,我就可以从任何节点遍历子树,完全消除Tree类,只需传递Node对象。

我宣布Node

代码语言:javascript
复制
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.
}

并将迭代器方法定义为

代码语言:javascript
复制
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语句:

代码语言:javascript
复制
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());
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

后来..。

代码语言:javascript
复制
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(),那么它也可以正常工作。

怎么回事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-18 01:44:36

shared_from_this有const超载和非const超载.见优先选择。在您的const begin中,this是指向const的指针,并调用const重载,该重载将shared_ptr返回给const。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47361542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档