return 取消引用映射迭代器时对临时对象的引用
return reference to temporary when dereferencing map iterator
考虑这段代码
#include <iterator>
#include <vector>
const int& foo(const std::vector<int>& x,unsigned i) {
auto it = x.begin();
std::advance(it,i);
return *it;
}
clang 和 gcc 都没有发出 errors/warnings,但是这个:
#include <iterator>
#include <map>
const std::pair<int,int>& bar(const std::map<int,int>& x,unsigned i){
auto it = x.begin();
std::advance(it,i);
return *it;
}
使用 clang 编译并使用 -Werror
结果:
<source>:14:12: error: returning reference to local temporary object [-Werror,-Wreturn-stack-address]
return *it;
^~~
和 gcc:
<source>: In function 'const std::pair<int, int>& bar(const std::map<int, int>&, unsigned int)':
<source>:14:13: error: returning reference to temporary [-Werror=return-local-addr]
return *it;
^~
是什么让 gcc 和 clang 拒绝 bar
,为什么 foo
没问题?
问题是来自 std::pair<const int,int>
的 std::map<int,int>
is not std::pair<int,int>
, but std::pair<const int,int>
. Then for return *it;
, a temporary std::pair<int,int>
has to be created and returned. (std::pair<int,int>
could be converted 的 value_type
。)临时文件将立即被销毁并使 returned 引用悬空。
要解决此问题,您可以将 return 类型更改为 const std::pair<const int,int>&
或 const std::map<int,int>::value_type &
。
考虑这段代码
#include <iterator>
#include <vector>
const int& foo(const std::vector<int>& x,unsigned i) {
auto it = x.begin();
std::advance(it,i);
return *it;
}
clang 和 gcc 都没有发出 errors/warnings,但是这个:
#include <iterator>
#include <map>
const std::pair<int,int>& bar(const std::map<int,int>& x,unsigned i){
auto it = x.begin();
std::advance(it,i);
return *it;
}
使用 clang 编译并使用 -Werror
结果:
<source>:14:12: error: returning reference to local temporary object [-Werror,-Wreturn-stack-address]
return *it;
^~~
和 gcc:
<source>: In function 'const std::pair<int, int>& bar(const std::map<int, int>&, unsigned int)':
<source>:14:13: error: returning reference to temporary [-Werror=return-local-addr]
return *it;
^~
是什么让 gcc 和 clang 拒绝 bar
,为什么 foo
没问题?
问题是来自 std::pair<const int,int>
的 std::map<int,int>
is not std::pair<int,int>
, but std::pair<const int,int>
. Then for return *it;
, a temporary std::pair<int,int>
has to be created and returned. (std::pair<int,int>
could be converted 的 value_type
。)临时文件将立即被销毁并使 returned 引用悬空。
要解决此问题,您可以将 return 类型更改为 const std::pair<const int,int>&
或 const std::map<int,int>::value_type &
。