C ++运算符*在b树的自定义迭代器中出错

时间:2011-10-17 10:10:24

标签: c++ iterator operator-overloading b-tree

我尝试使用自定义迭代器中的运算符*()返回值时出现以下错误。

 error: invalid initialization of non-const reference of type 'char&' from a temporary of type 'char'

如果有人能够帮助我,那就太棒了!

代码的细节如下:

测试代码:

  for(btree<char>::iterator itr = tree.begin(); itr != tree.end(); ++itr) {

    cout << *itr << " "; // <- this line complains about the * operator.
  }

运算符*()代码:

template <typename T> typename btree_iterator<T>::reference btree_iterator<T>::operator*() const {

  return pointee_->value(); // <- this line is where the error above is produced from.
}
来自btree_iterator类的

pointee_是一个私有变量,定义如下:

btree_node<T>* pointee_;

引用在btree_iterator类中键入以下内容:

  typedef T&       reference;

value()在btree_node类中定义如下:

T value() const;

// function definition.
template <typename T> T btree_node<T>::value() const { return value_; }

值最初通过它的构造函数存储到btree_node中,如下所示:

template <typename T> btree_node<T>::btree_node(const T& elem) : value_(elem), nextCont_(NULL), prevCont_(NULL), nextNode_(NULL), prevNode_(NULL) {}

如果我错过了包含任何重要信息,请告诉我,如果我做了就道歉!

基于错误,听起来我正在尝试返回对局部变量的引用。迭代器本身可能是本地的,但它返回的值不应该是,因为节点构造函数最初接受引用,并将其存储到节点中。

提前致谢,并致以问候!

2 个答案:

答案 0 :(得分:3)

您正在尝试使用对临时变量的引用

template <typename T> T btree_node<T>::value() const { return value_; }
                     ^^^

这将返回value_的临时副本。

template <typename T> typename btree_iterator<T>::reference btree_iterator<T>::operator*() const {
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  return pointee_->value(); // <- this line is where the error above is produced from.
}

这将返回对该临时副本的引用。您最有可能希望value()返回引用,但这取决于您 - 引用允许您btree的客户端更改内容。特别是如果树是基于节点的值排序的,您可能不希望允许这样。想一想这与您的设计有什么关系。

答案 1 :(得分:1)

pointee_->value()返回一个基本上是新副本的值。因此,此值在operator*中是本地值,您无法返回对该值的引用。

我建议就像大多数容器一样,即同时拥有iteratorconst_iterator,而const_iterator返回一个const引用,迭代器返回一个引用。同样的原则适用于value()。有版本返回ref和const ref。

如果您想要处理副本,可以从客户端代码中的引用创建它们。如果您不想允许对值进行操作,只需删除(或使私有或其他)非const部分。它认为它也适合人们使用你的btree期望:

迭代器不会在某处复制,而是在数据结构内部的数据上进行迭代。如果你想要副本,你可以制作它们。