samedi 30 mai 2020

Passing an lvalue to a function accepting a rvalue reference should fail, but doesn't [duplicate]

The following program

#include <iostream>

class C {};

void f(C&& c) {}

int main() {
    C c;
    f(c);

    return 0;
}

outputs the following compilation error on g++:

cannot bind rvalue reference of type 'C&&' to lvalue of type 'C'

That makes sense to me - f() requests an rvalue reference, but we have passed in an lvalue.

However, I encountered an answer on SO where the writer seems to do exactly this - only to have it work. Code from the answer (comments mine):

#include <iostream>
#include <string>
#include <utility>

void overloaded_function(std::string& param) {
  std::cout << "std::string& version" << std::endl;
}
void overloaded_function(std::string&& param) {
  std::cout << "std::string&& version" << std::endl;
}

template<typename T>
void pass_through(T&& param) {
  overloaded_function(std::forward<T>(param));
}

int main() {
  std::string pes;
  pass_through(pes); // Calling pass_through(T&&) with an lvalue
  pass_through(std::move(pes));
}

It does compile also on my machine.

So what's happening here - why does the first piece of code fail to compile, while the second one doesn't?

Is it related to the fact that the function in the second instance is templated? And if so, what it the logic behind what's happening?

Aucun commentaire:

Enregistrer un commentaire