sp2danny :
The following short program
#include <vector>
#include <iostream>
std::vector<int> someNums()
{
return {3, 5, 7, 11};
}
class Woop
{
public:
Woop(const std::vector<int>& nums) : numbers(nums) {}
void report()
{
for (int i : numbers)
std::cout << i << ' ';
std::cout << '\n';
}
private:
const std::vector<int>& numbers;
};
int main()
{
Woop woop(someNums());
woop.report();
}
have a dangling reference problem, that no compiler seems to warn about. The issue is that temporaries can be bound to const-refs, which you may then keep around. The question then is; Is there a 'best practices' method of avoiding getting into this problem? Preferably one that does not involve sacrificing const correctness, or always making copies of big objects.
user7860670 :
In situation when some method keeps a reference after returning it is a good idea to utilize std::reference_wrapper
instead of normal reference:
#include <functional>
class Woop
{
public:
using NumsRef = ::std::reference_wrapper<const std::vector<int>>;
Woop(NumsRef nums) : numbers_ref{nums} {}
void report()
{
for (int i : numbers_ref.get())
std::cout << i << ' ';
std::cout << '\n';
}
private:
NumsRef numbers_ref;
};
- it already comes with a set of overloads preventing binding of rvalues and unintended passing of temporaries, so there is no need to bother with an extra prohibited overload taking a rvalue
Woop (std::vector<int> const &&) = delete;
for your method:
Woop woop{someNums()}; // error
woop.report();
- it allows implicit binding of lvalues so it won't break existing valid invocations:
auto nums{someNums()};
Woop woop{nums}; // ok
woop.report();
- it allows explicit binding of lvalues which is a good practice to indicate that caller will keep the reference after returning:
auto nums{someNums()};
Woop woop{::std::ref(nums)}; // even better because explicit
woop.report();
Guess you like
Origin http://43.154.161.224:23101/article/api/json?id=367805&siteId=1