我在學習std::forward
。我寫了一個小程序來測試,如果我們不轉發參數另一個函數調用之前調用std::forward
會發生什麼:爲什麼C++字符串不需要std :: forward來調用所需的函數?
#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;
}
在這裏,我想一個左值和一個右值轉發來自test_forward_wrapper()
到test_forward_inner()
。運行此程序會輸出:
& example
& example
& hello
&& hello
對於std::string
S,目標內部函數被調用,但是對於我自己的類只有左值版本被調用。只有在將參數傳遞給內部函數之前調用std::forward
才能調用右值版本。
這裏的區別是什麼?據我所知,根據參考摺疊規則,當包裝被調用Example()
時,將推導出右值T
爲Example
和arg
將具有類型Example &&
因此應該調用內函數的右值版本。
而對於其他情況,如std::string
這裏的情況,調用了內部函數的正確版本,那麼我們可以在這裏刪除std::forward
?如果不是,會發生什麼(可能是壞事)?
最重要的部分是,包裝物爲模板化(所以沒有強迫在呼叫發生時),而內部功能不是,只接受'的std :: string',這意味着轉化爲'string'發生然後(爲內部函數提供r值參考),不涉及轉發。 – ShadowRanger
'「hello」'不是'const char *',它是一個'const char [6]',可以衰減爲'const char *'。 。 –
^(並且在這種情況下不衰減) –