While searching a solution for calling a function that accepts both lvalue and rvalue references I wrote the following piece of code (no, I will never do that again, I promise).
The goal was providing a function that both accepts lvalue and rvalue references, I did not want to write two functions or to really care about lvalue/rvalue on the caller's side. Therefore, I thought of providing some macro/function that wraps a parameter so it can be passed whether it's an l/rvalue - in this case get_addr.
In no case I would want to change data passed to the function.
template<typename T>
std::shared_ptr<T> get_addr(T t) {
std::shared_ptr<T> p(new T(t));
return p;
}
int get_value(int x){
return x * 2;
}
void print_value(int* p){
cout << *p << endl;
}
int main() {
print_value(get_addr(get_value(42)).get());
}
While that code is working fine for me, I doubt it is safe. My guess: after calling get() from shared_ptr, the result of get_value() is not necessary anymore and could get dismissed. So, print_value could receive an invalid reference. Does that make sense? In any case, I do not like my code provided. I solved the issue by using a temporary variable.
Nevertheless, I'm still curious if there was any better solution for that problem. From the syntax' point of view, I'd like best only one function "void print_value(int&& p)" that accepts both l/rvalues. I've looked at move semantics, l/rvalue conversions but didn't find a solution that really looks nice.
In no case I would want to change data passed to the function.
What's wrong with this then?
void print_value(int p){
cout << p << endl;
}
Or the following, if you don't want to copy some expensive type.
void print_value(T const& p){
cout << p << endl;
}