The following code gives the same output, of course using std::forward_like, you can put the whole self.member in the bracket, is that the whole point? (compile using clang 18)
#include <print>
#include <utility>
auto g(int &&) { std::println("rvalue g"); }
auto g(int const &&) { std::println("const rvalue g"); }
auto g(int &) { std::println("lvalue g"); }
auto g(const int &) { std::println("const lvalue g"); }
struct S {
int member;
auto use_foward_like(this auto &&self) {
g(std::forward_like<decltype(self)>(self.member));
}
auto use_foward(this auto &&self) {
g(std::forward<decltype(self)>(self).member);
}
};
int main() {
S s;
std::println("use forward_like:");
s.use_foward_like();
std::as_const(s).use_foward_like();
std::move(s).use_foward_like();
static_cast<S const &&>(s).use_foward_like();
std::println("\nuse forward:");
s.use_foward();
std::as_const(s).use_foward();
std::move(s).use_foward();
static_cast<S const &&>(s).use_foward();
}
As my understanding goes:
std::forward helps you pass the argument in a way that keeps its original type.
std::forward_like helps you pass the argument in a way that mimics the type of another expression, keeping it consistent with that expression's original type.
It is like one forwards the original while the other forwards an imitation that matches the original