简体   繁体   中英

Error with returning reference to temporary object

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.

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)
{ ... }

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.


Minimal example

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 ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM