1
#include <bits/stdc++.h>
using namespace std;

template<class T = string>
void f(T &&s) {
    cout << s << endl;
}

int main() {
    string s("1234");
    f(s);
    f("1234");

    return 0;
}

Can be compiled.

#include <bits/stdc++.h>
using namespace std;

void f(string &&s) {
    cout << s << endl;
}

int main() {
    string s("1234");
    f(s);
    f("1234");

    return 0;
}

I replace T to string, the code can not be compiled.

error:

❯ g++-8 -std=c++11 a.cpp && ./a.out
a.cpp: In function 'int main()':
a.cpp:10:11: error: cannot bind rvalue reference of type 'std::__cxx11::string&&' {aka 'std::__cxx11::basic_string<char>&&'} to lvalue of type 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'}
         f(s);
           ^
a.cpp:4:10: note:   initializing argument 1 of 'void f(std::__cxx11::string&&)'
     void f(string &&s) {
          ^

I'm so confused.

cpplearner
  • 13,776
  • 2
  • 47
  • 72
comwrg
  • 41
  • 1
  • 8

1 Answers1

0

There are some exceptions to template type inference. If a function template receives an rvalue reference and we passed in an lvalue reference,compiler will inference it as a lvalue reference.That is the reason that std::move works correctly.

template <typename T>
typename remove_reference<T>::type&& move(T&& t)
{
    return static_cast<typename remove_reference<T>::type&&>(t);
}
郭一凡
  • 36
  • 3