我在学习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 *'。 。 –
^(并且在这种情况下不衰减) –