templates - Why C++ strings do not need std::forward to call the desired function? -


i'm learning std::forward. wrote short program test happen if not call std::forward before forwarding arguments function call:

#include <iostream> #include <typeinfo> #include <string> using namespace std;  class example { };  ostream &operator << (ostream &os, const example &e) { os << "yes!"; return os; }  void test_forward_inner(const example &e) { cout << "& " << e << endl; } void test_forward_inner(example &&e) { cout << "&& " << e << endl; }  void test_forward_inner(const string &e) { cout << "& " << e << endl; } void test_forward_inner(string &&e) { cout << "&& " << e << endl; }  template <typename t> void test_forward_wrapper(t &&arg) {     test_forward_inner(arg); }  int main() {     example e;     test_forward_wrapper(e);     test_forward_wrapper(example());      cout << endl;      string s("hello");     test_forward_wrapper(s);     test_forward_wrapper("hello");      return 0; } 

here tried forward lvalue , rvalue test_forward_wrapper() test_forward_inner(). running program gives output:

& example & example  & hello && hello 

for std::strings, desired inner function called, own class lvalue version called. if call std::forward before passing arguments inner function can rvalue version called.

what makes difference here? know, according reference collapsing rules, when wrapper called example(), rvalue, t deduced example , arg have type example && rvalue version of inner function should called.

and, other situations std::string case here, correct version of inner function called, can remove std::forward here? if not, (maybe bad) happen?

note "hello" not std::string, it's const char[6]. , test_forward_wrapper() function template, template argument t deduced char const (&)[6] it.

inside test_forward_wrapper(), test_forward_inner() called const char[6], need converted std::string @ first. temporary std::string, i.e. rvalue, preferred bound rvalue reference , that's why test_forward_inner(string &&) called.

passing exact std::string test_forward_wrapper() same result.

test_forward_wrapper(std::string("hello")); 

Comments