返回对临时对象的引用时出错

时间:2016-02-12 13:42:24

标签: c++

我在c ++中有以下模板功能

template<class S, class T> const T& safe_retrieve
(vector<T> const& data, vector<S> const& keys, const S& key)
{
    assert(data.size() == keys.size());
    typename vector<S>::const_iterator it = binary_find(keys.begin(), keys.end(), key);
    assert(it != keys.end());
    size_t index = static_cast<size_t>(it - keys.begin());
    return data.at(index);
}

但是,我收到了错误:

 error: returning reference to temporary [-Werror=return-local-addr]

我理解这个错误的含义,但我不明白为什么我返回的引用是暂时的。

2 个答案:

答案 0 :(得分:4)

只是将我的评论转化为正确答案:

您的代码假定vector<T>::at() const始终返回const T&。但是,情况并非总是如此:template specialization for std::vector<bool>具有不同类型的引用(proxy for the respective bit in the internal bit vector implementation代替普通引用,而普通bool代替const引用)。在这种情况下,at()会返回一个临时值,您无法使用引用传递它。

解决方案是按如下方式声明您的功能:

template <class S, class T>
typename std::vector<T>::const_reference  // sic!
safe_retrieve(std::vector<T> const& data,
              std::vector<S> const& keys,
              const S& key)
{ ... }

答案 1 :(得分:0)

由于datastd::vector<T> const&,因此可能是暂时的:

safe_retrieve(std::vector<int>{10,20}, std::vector<int>{1,2}, 2);

使用safe_retrieve时,将返回临时值。

最小的例子

来源:

#include <iostream>
#include <vector>

int const& get(std::vector<int> const& data)
{
    return data.at(0);
}

int main() {
    int const& data = get(std::vector<int>{42, 0});
    std::cout << data << std::endl;
}

汇编:

$ g++ -std=c++11 -O2 -Wall -Werror main.cpp && ./a.out

执行命令

$ ./a.out
0

它应该是42,你好UB;)