Should std::forward be used when the forwarding reference is not passed to another function but a member function is called on it?

Viewed 62

Examples of std::forward I've seen use it when passing the argument to another function, such as this common one from cppreference:

template<class T>
void wrapper(T&& arg) 
{
    // arg is always lvalue
    foo(std::forward<T>(arg)); // Forward as lvalue or as rvalue, depending on T
}

It also has a more complicated case:

if a wrapper does not just forward its argument, but calls a member function on the argument, and forwards its result

// transforming wrapper 
template<class T>
void wrapper(T&& arg)
{
    foo(forward<decltype(forward<T>(arg).get())>(forward<T>(arg).get()));
}

But what happens when I only call the member function without passing the result to another function?

template<class T>
auto wrapper(T&& arg)
{
    return std::forward<T>(arg).get();
}

In this case, is it useful to call std::forward or is arg.get() equivalent? Or does it depend on T?

EDIT: I've found a case where they are not equivalent;

#include <iostream>

struct A {
    int get() & {
        return 0;
    }

    int get() && {
        return 1;
    }
};

template<class T>
auto wrapper_fwd(T&& arg)
{
    return std::forward<T>(arg).get();
}

template<class T>
auto wrapper_no(T&& arg)
{
    return arg.get();
}

wrapper_fwd(A{}) returns 1 and wrapper_no(A{}) returns 0.

But in my actual use-case arg is a lambda and operator() isn't overloaded like this. Is there still a possible difference?

0 Answers
Related