下面是从this question带来的代码。
// [I]
void overloaded_function(const std::string& param) {
std::cout << "const std::string& version: " << param << '\n';
}
// [II]
void overloaded_function(std::string&& param) {
std::cout << "std::string&& version: " << param << '\n';
}
template <typename T>
void pass_through_f(T&& param) {
overloaded_function(std::forward<T>(param));
}
template <typename T>
void pass_through(T&& param) {
overloaded_function(param);
}
int main() {
std::string str = "Hello World";
pass_through_f(str); // (1)
pass_through_f(std::move(str)); // (2)
std::cout << "----------\n";
pass_through(str); // (3)
pass_through(std::move(str)); // (4)
return 0;
}const std::string& version: Hello World
std::string&& version: Hello World
----------
const std::string& version: Hello World
const std::string& version: Hello World当我使用pass_through_f()时,(1)和(2)之间的结果是不同的,但是在调用pass_though()时它们是相同的。
我的问题是,(4)的结果如何与(3)相同?下面是我认为的类型推断过程:
(4)中,某些函数的返回值为r-值,因此T of pass_through()被推断为与传递的参数相同的类型。因此,T是std::string&&。std::string&&是r值引用,r值引用是r值,因此它调用overloaded_function() [II].因此,当使用std::forward时,它的结果是相同的。但结果与我的想法不同。我想我误解了std::forward的工作方式。
发布于 2019-08-07 18:22:30
问题是在
template <typename T>
void pass_through(T&& param) {
overloaded_function(param);
}param是一个命名变量。因为它有一个名称,所以它是一个lvalue,即使它是对rvalue的引用。因为它是一个lvalue,所以调用lvalue函数。
如果它作为rvalue出现,则需要std::forward将其“重新转换”回rvalue。
还请注意,T不是string&&。由于您传递了一个string&&,所以T&&会将T演绎给string,并保留&&以使其成为一个rvalue引用。
https://stackoverflow.com/questions/57400153
复制相似问题