我在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]
我理解这个错误的含义,但我不明白为什么我返回的引用是暂时的。
答案 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)
由于data
是std::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;)