Search code examples
c++shared-ptrrvalue

pointer to rvalue


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.


Solution

  • 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;
    }