解引用运算符不起作用(语法问题?)

时间:2015-11-15 09:38:55

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

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

现在因为它返回一个指向包含各种成员的_node对象的指针,我的理解是必须提供一个解除引用运算符重载,以便_node知道在解除引用时返回什么

在取消引用运算符定义中,我尝试返回value的{​​{1}},这似乎都很合乎逻辑,因为_node会返回begin,这意味着取消引用_node 1}}会给我begin后面的value。显然不是,因为MSVC编译器告诉我:_node

binary '<<': no operator found which takes a right-hand operand of type '_node<TType>' (or there is no acceptable conversion)

编辑:: 感谢 Joachim Pileborg 提出建议。像魅力一样工作,有以下变化:

#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"
}

4 个答案:

答案 0 :(得分:1)

您正在返回一个指针:

_node<TType> *begin();

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

  1. 取消引用指针
  2. 致电您的运营商(已为_node<...>定义,而不是_node<...> *,不会调用它而不是简单的取消引用)
  3. 也许,更好的是替换

    TType operator*();
    

    使用用户定义的转化,return this->key;

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

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

答案 1 :(得分:1)

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

因此,您可以使用两个解除引用运算符来解决您的问题:

**i.begin()

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

答案 2 :(得分:1)

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

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

如果实现迭代器,请不要将节点类暴露给最终用户。

如果你想要任何特别不符合任何内容的列表,你可能最好不要重载任何运算符。使用getValue或其他内容。

答案 3 :(得分:0)

问题在于这一行:

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

您还没有定义运算符&lt;&lt;将其中一个对象传输到ostream。