【发布时间】:2013-07-09 03:13:53
【问题描述】:
我有以下代码直接来自: http://www.justsoftwaresolutions.co.uk/cplusplus/rvalue_references_and_perfect_forwarding.html
在 g++ 4.8.1 编译为:g++ -std=c++11 testforward.cpp -o testforward.exe
#include <cstdlib>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
class X
{
std::vector<double> data;
public:
X():
data(100000) // lots of data
{}
X(X const& other): // copy constructor
data(other.data) // duplicate all that data
{}
X(X&& other): // move constructor
data(std::move(other.data)) // move the data: no copies
{}
X& operator=(X const& other) // copy-assignment
{
data=other.data; // copy all the data
return *this;
}
X& operator=(X && other) // move-assignment
{
data=std::move(other.data); // move the data: no copies
return *this;
}
};
void g(X&& t)
{
std::cout << "t in g is rvalue" << std::endl ;
}
void g(X& t)
{
std::cout << "t in g is lvalue" << std::endl ;
}
template<typename T>
void f(T&&t)
{
g(std::forward<T>(t)) ;
}
void h(X &&t)
{
g(t) ;
}
int main()
{
X x;
f(x); // 1
f(X()); // 2
//h(x); //compile error
h(X()); // 3
}
根据作者描述如下:
当你将右值引用与函数模板结合起来时,你会得到一个有趣的交互:如果函数参数的类型是对模板类型参数的右值引用,那么如果传递了左值,则类型参数会被推断为左值引用,否则是普通类型...
这个测试的结果输出是:
t in g is lvalue
t in g is rvalue
t in g is lvalue
f(x) get "t in g is lvalue" 和预期一样!!
f(X()) get "t in g is rvalue" 是的,这就是 std::forward 用于
h(X()) get "t in g is lvalue" ,这是我的问题,你可以看到函数 h 不是模板函数,正如作者所描述的“当你将右值引用与函数模板结合起来时,你会得到一个有趣的交互”,但事实并非如此 这个函数输出“t in g is lvalue”,意味着这个有趣的交互不仅发生在模板函数中,也发生在普通函数中!!
如果我将代码更改为:
void h(X &&t)
{
g(std::forward<X>(t)) ;
}
我会得到“t in g is rvalue”!!!
根据测试,我可以说作者描述的“当你将右值引用与函数模板结合起来时,你会得到一个有趣的交互”实际上不仅适用于模板函数,它也适用于普通函数,或者我的英语不好,所以我无法理解这个描述吗?!
编辑:
void h(X &&t)
{
g(t) ;
}
void h(X &t)
{
g(t) ;
}
h(x); //get "t in g is lvalue"
h(X()); //get "t in g is lvalue"
=====================================================
void h(X &&t)
{
g(std::forward<X>(t)) ;
}
void h(X &t)
{
g(std::forward<X>(t)) ;
}
h(x); //get "t in g is rvalue"
h(X()); //get "t in g is rvalue"
看起来只有在模板函数中,我会得到std::forward的cprrect用法!!!
【问题讨论】:
标签: c++ c++11 perfect-forwarding