代码之家  ›  专栏  ›  技术社区  ›  463035818_is_not_an_ai

取消引用映射迭代器时返回对临时的引用

  •  6
  • 463035818_is_not_an_ai  · 技术社区  · 7 年前

    考虑此代码

    #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都不会发出错误/警告,但这:

    #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 好的

    1 回复  |  直到 7 年前
        1
  •  8
  •   songyuanyao    7 年前

    问题是 value_type 属于 std::map<int,int> 不是 std::pair<int,int> 但是 std::pair<const int,int> 。然后用于 return *it; ,临时 标准::成对(&L);int,int> 必须创建并返回。( 标准::成对(&L);int,int> 可能是 converted 从…起 标准::成对(&L);常数int,int> .)临时文件将立即销毁,并将返回的引用挂起。

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