为什么我收到以下错误:"returning reference to temporary [-Werror=return-local-addr]"



给定以下代码:

#include <set>
using std::set;
class Pool {
set<int> s;
public:   
typedef typename set<int>::iterator Iterator;
const Iterator& begin() const {
return s.begin(); //** error
}
};    

为什么我收到以下错误(我理解错误的含义,但是,我不明白为什么在这种情况下会出现它(?

返回对临时 [-Werror=return-local-addr] 的引用

我该如何解决它?

set<...>::begin函数按值返回其迭代器。由于您不将该值存储在任何地方,因此它是一个临时值,并且您实际上无法引用临时值。

简单的解决方案是让您的函数按(非常量(值返回。

const Iterator& begin() const {
return s.begin(); //** error
}

是非法的,因为s.begin()的结果是一个临时对象,因此您无法返回对它的引用。也许如果你看看这个等效的代码会更清楚?

const Iterator& begin() const {
Iterator it = s.begin();
return it; //** error
}

无论如何,返回对迭代器的常量引用没有多大意义,因为您将无法移动迭代器指向的位置。您应该始终按值返回迭代器,这样调用方就可以自由地复制迭代器并修改其位置。例如,如果可以让代码编译以下调用代码将不起作用:

Pool p;
const Pool::Iterator& it = p.begin();
++it; //error it is constant

用户可以通过将返回的引用复制到新对象中来修复其代码:

Pool p;
Pool::Iterator it = p.begin();
++it; //no error

由于您的用户将无法使用该引用,因此您无法仅按值返回其更好:

const Iterator begin() const {
return s.begin();
}

请注意,std::set与大多数其他容器不同,并且不允许通过其迭代器修改值:https://en.cppreference.com/w/cpp/container/set/begin

由于迭代器和const_iterator都是常量迭代器(实际上可能是同一类型(,因此不可能通过这些成员函数中的任何一个返回的迭代器来改变容器的元素。

相关内容

最新更新