【问题标题】:Dereference operator doesn't work (syntax issue?)取消引用运算符不起作用(语法问题?)
【发布时间】:2016-02-16 12:59:14
【问题描述】:

所以我有一个非常简单的单链表实现示例。我有一个begin 函数作为forward_list 的公共成员,它返回指向列表的第一个(根)元素的指针。

现在,由于它返回一个指向包含各种成员的 _node 对象的指针,据我了解,必须提供取消引用运算符重载,以便 _node 知道在取消引用时返回什么。

在取消引用运算符定义中,我尝试返回_nodevalue,这一切似乎都很合乎逻辑,因为begin 返回一个_node,这意味着取消引用begin 会给我value_node 后面。显然不是,正如 MSVC 编译器告诉我的那样:binary '<<': no operator found which takes a right-hand operand of type '_node<TType>' (or there is no acceptable conversion)

#include <iostream>
#include <cstddef>

//forward declarations
template<class TType> class forward_list;

template<class TType>
class _node
{
private:
    TType key;
    _node *next;

    friend class forward_list<TType>;
public:
    TType operator*() { return this->key; } //problem is here
};

template<class TType>
class forward_list
{
private:
    _node<TType> *_root;
    _node<TType> *_tail;

    std::size_t _size;
private:
    void _add_node_front(const TType &new_key)
    {
        _node<TType> *new_node = new _node<TType>{ new_key, this->_root };

        if (this->_root == nullptr)
            this->_tail = new_node;

        this->_root = new_node;

        ++this->_size;
    }
public:
    forward_list() : _root(nullptr), _tail(nullptr), _size(0) {}

    void push_front(const TType &new_key) { this->_add_node_front(new_key); }

    _node<TType> *begin() { return this->_root; }
};

int main()
{
    forward_list<int> l;
    l.push_front(23);
    l.push_front(57);
    l.push_front(26); //26 57 23

    std::cout << *l.begin(); //expected to print out "26"
}

编辑:: 感谢 Joachim Pileborg 的建议。具有以下更改的魅力:

_node<TType> begin() { return *this->_root; }

【问题讨论】:

    标签: c++ c++11 operator-overloading


    【解决方案1】:

    你正在返回一个指针:

    _node<TType> *begin();
    

    所以你需要取消引用两次:

    1. 取消引用指针
    2. 调用您的操作员(它是为_node&lt;...&gt; 定义的,而不是为_node&lt;...&gt; * 定义的,它不会被调用而不是简单的取消引用)

    或许换个方式会更好

    TType operator*();
    

    使用用户定义的转换,这将return this-&gt;key;:

    operator TType& ();
    operator TType const& () const;
    

    而且您不需要第二次取消引用。

    【讨论】:

      【解决方案2】:

      你错误的直接原因是begin返回一个_node*,而你重载的operator*需要一个_node

      如果你想实现一个符合标准的容器,你的begin 操作符应该返回一个迭代器(按值),而不是一个(指向一个)节点。这个迭代器应该实现operator*(还有operator++ 和其他一些东西)。节点类不适合作为迭代器。你需要一个单独的课程。谷歌类似“实现我自己的迭代器”。

      如果您实现迭代器,请不要将您的节点类公开给最终用户。

      如果您只想要任何不符合任何特定内容的列表,您最好不要重载任何运算符。使用getValue 或其他东西。

      【讨论】:

        【解决方案3】:

        问题是您取消引用 指针,它为您提供了 _node&lt;int&gt; 类型的对象,然后您可以再次使用取消引用运算符。

        所以你可以通过使用两个解引用运算符来解决你的问题:

        **i.begin()
        

        另一种解决方案是按值返回节点,而不是返回指向它的指针,这是标准容器中迭代器的功能。

        【讨论】:

          【解决方案4】:

          问题出在这一行:

          std::cout << *l.begin(); //expected to print out "26"
          

          您尚未定义运算符

          【讨论】:

            猜你喜欢
            • 2012-06-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-02-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多