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

Dereference operator doesn't work (syntax issue?)

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

现在因为它 return 是指向包含各种成员的 _node 对象的指针,据我所知,必须提供取消引用运算符重载才能 _node知道取消引用时 return 的内容。

在取消引用运算符定义中,我尝试 returning _nodevalue,这看起来很合乎逻辑,因为 begin return 是一个_node 这意味着取消引用 begin 会给我 _node 后面的 value。显然不是,正如 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"
}

EDIT:: 感谢 Joachim Pileborg 的建议。具有以下变化的魅力:

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

您正在返回一个指针:

_node<TType> *begin();

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

  1. 取消引用指针
  2. 调用您的运算符(它是为 _node<...> 定义的,而不是为 _node<...> * 定义的,它不会被调用而不是简单的取消引用)

也许,更好的方法是替换

TType operator*();

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

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

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

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

所以您可以使用两个取消引用运算符来解决您的问题:

**i.begin()

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

问题出在这一行:

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

您尚未定义 operator<< 以将这些对象之一流式传输到 ostream。

您出错的直接原因是 begin return 是一个 _node*,而您的超载 operator* 需要一个 _node

如果你想实现一个符合标准的容器,你的begin操作符应该return一个迭代器(按值),而不是一个(指针到 a) 节点。这个迭代器应该实现 operator* (还有 operator++ 和一堆其他东西)。节点 class 不适合作为迭代器。您需要一个单独的 class。 Google 类似于 "implementing my own iterators".

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

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