0
votes

I found the below link which said "lvalue and rvalue reference interface can combine in one". Pass lvalue to rvalue

but when I take it for example. compile error appeared cannot bind ‘std::string {aka std::basic_string}’ lvalue to ‘std::string&& {aka std::basic_string&&}’. Below is my implementation.

#include <iostream>
#include <string>

using namespace std;

void g(string &&b) {
    cout << b << endl;
}

void g(const string &b) {
    cout << b << endl;
}

void f(string &&a) {
    g(std::forward<string>(a));
}

int main()
{
    f("1122");
    string a("222");
    f(a);
    return 0;
}

I mean "void f(string &&a)" and "void f(const string &a)" can combine in one. Then we just need to call "void f(string &&a)", which can both receive rvalue reference and lvalue by preface forward.

--------- Add description

this may be call universal reference

1
Which answer to the linked question are you trying to follow? The one that uses a template (unlike your code) or the one that directs execution to a unified function (your code goes from a unified function)? Neither is a perfect match to what you've done, and you linked to the question instead of to a specific answer... - JaMiT

1 Answers

1
votes

To combine an r-value reference and l-value reference into a single reference, you need to use a so called universal reference. These are defined in C++ via auto && or a template with a && reference. See for example What is move semantics? , though, quite exceptionally, I guess you'll find more approachable explanations outside of stackoverflow. Search for "universal reference C++".

Now, back to your code. All you need is this:

template <typename T>
void f(T &&a) 
{
    g(std::forward<string>(a));
}

That's it. A universal reference defined via a template plus a &&-reference. Notice that I had to replace string with T.

However, simplicity is our best friend. If you don't need a template, why not go for the old, good const reference?

void f(const string & a) 
{
  g(a);
}

To me, it is the preferable solution.