Reputation: 84
I have a following template function in 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);
}
However, I'm getting an error:
error: returning reference to temporary [-Werror=return-local-addr]
I understand the meaning of this error, but I don't see why the reference that I'm returning is temporary.
Upvotes: 1
Views: 714
Reputation: 40070
Since data
is a std::vector<T> const&
, it could be a temporary:
safe_retrieve(std::vector<int>{10,20}, std::vector<int>{1,2}, 2);
With that use of safe_retrieve
, a temporary would be returned.
Source:
#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;
}
Compilation:
$ g++ -std=c++11 -O2 -Wall -Werror main.cpp && ./a.out
Run:
$ ./a.out
0
It should be 42, hello UB ;)
Upvotes: 0
Reputation: 5668
Just to turn my comment into a proper answer:
Your code assumes that vector<T>::at() const
always returns a const T&
. However, that is not always the case: The template specialization for std::vector<bool>
has a different type of reference (a proxy for the respective bit in the internal bit vector implementation in lieu of a normal reference, and a plain bool
value in lieu of a const reference). In this case, at()
returns a temporary, which you cannot pass on using a reference.
The solution is to declare your function as follows:
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)
{ ... }
Upvotes: 5