在解除引用map迭代器时返回对临时的引用

for*_*818 5 c++ warnings dictionary 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;
}
Run Code Online (Sandbox Code Playgroud)

clang和gcc都没有发出错误/警告,但是:

#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;
}
Run Code Online (Sandbox Code Playgroud)

clang编译并使用-Werror结果:

<source>:14:12: error: returning reference to local temporary object [-Werror,-Wreturn-stack-address]
    return *it;
           ^~~
Run Code Online (Sandbox Code Playgroud)

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;
             ^~
Run Code Online (Sandbox Code Playgroud)

是什么让gcc和clang拒绝bar,为什么foo还好?

son*_*yao 7

问题是那value_typestd::map<int,int>不是std::pair<int,int>,而是std::pair<const int,int>.然后return *it;,std::pair<int,int>必须创建并返回临时.(std::pair<int,int>可以从.转换std::pair<const int,int>.)临时将被立即销毁并留下返回的引用悬空.

要解决问题,您可以将返回类型更改为const std::pair<const int,int>&const std::map<int,int>::value_type &.