【发布时间】:2020-12-04 18:01:59
【问题描述】:
我正在尝试在 C++ 中实现一个通用链表和链表迭代器。我有一个节点结构如下
template <typename T>
struct Node
{
T m_data;
Node<T>* m_next;
};
我还有一个链表迭代器,它是一个模板,因此它可以生成常规迭代器和const 迭代器。
template <typename NodeType>
class LinkedListIterator
{
private:
NodeType* m_node;
public:
LinkedListIterator(NodeType* n);
T& operator*() const;
};
我的问题是如何正确声明operator*() 函数?我的期望是像下面这样的东西应该可以工作
LinkedListIterator<const Node<T>> my_iter(some_node_pointer);
*my_iter = new_value; // should not work
我知道在 operator*() 中返回 T 没有意义,因为此类无权访问 Node 类中的类型名。
我找到了一种解决方法,方法是为 Node 类中的类型创建别名,就像这样
template <typename T>
struct Node
{
typedef T type_value;
// rest of Node class...
};
现在我可以在我的迭代器类中执行以下操作
template <typename NodeType>
class LinkedListIterator
{
public:
typename NodeType::type_value& operator*() const;
};
这似乎有效并且会返回正确的值。所以我的问题真的应该是,这是实现这一点的最佳方式吗?我需要typedef 来创建别名以便我可以使用该类型吗?或者有没有办法确定LinkedListIterator 类中的类型?
【问题讨论】:
-
typedef(或更好的 C++11 及更高版本中的using)是处理此问题的一种方法,是的。另一种方法是只使用auto,例如:auto& operator*() const { return m_node->m_data; } -
“内部类型的别名”是 C++ 库本身一直在做的事情。您会惊讶地发现每个 C++ 容器的
value_type成员,以及它的实际来源。你猜对了。别名。 -
虽然不相关,但我发现
boost::typeindex::type_id_with_cvr<decltype(arg) or T>().pretty_name();有助于查看 T 和参数的类型。
标签: c++ templates iterator typename