c++中函数形参中的右值引用
C++, rvalue references in function parameters
我正在努力理解rvalue
参考。我已经看到它们是如何在构造函数中使用的,像std::move
和std::forward
这样的东西,但我仍然不明白为什么这不起作用:
void func(string&& str)
{
cout << str << endl;
}
int main(int argc, char* argv[])
{
string s("string");
func(s);
}
template<typename T>
void func(T&& str)
{
cout << str << endl;
}
int main(int argc, char* argv[])
{
string s("string");
func(s);
}
为什么它与函数模板版本一起工作?
就像@Peter说的,T
的类型被推断为string&
, c++的引用崩溃规则说:
T&,⇒T&//from c++ 98
T&和;,⇒T&//新增c++ 0x
T&,,⇒T&//新增c++ 0x
T&和;,,⇒T&和;//新增c++ 0x
所以func
的实例化实际上是:
void func(string& str)
它成功了
除了@ songyuananyao的回答之外,还有一些正式的解释:
N4296::14.8.2.1 [temp.deduct.call]
:
通过比较每个函数来推导模板实参模板参数类型(称其为P)与类型相对应如下所述,调用的实参(称之为A)
N4296::14.8.2.1/3 [temp.deduct.call]
:
一个转发引用为对cv不限定模板形参的右值引用。如果P是a转发引用和参数是一个左值,类型为" lvalue "引用A "代替A进行类型推导。
标准还提供了以下示例:
template <class T> int f(T&& heisenreference);
template <class T> int g(const T&&);
int i;
int n1 = f(i); // calls f<int&>(int&)
int n2 = f(0); // calls f<int>(int&&)
int n3 = g(i); // error: would call g<int>(const int&&)
因为在模板内部&&
有不同的含义,所以它被称为通用引用。
具有&&
形参(通用引用)的模板函数意味着该形参可以用作引用或右值引用。
在你的例子中,模板被推断为string&
,这就是它工作的原因。
要使用原始函数,您必须这样做:
void func(string&& str)
{
cout << str << endl;
}
int main(int argc, char* argv[])
{
string s("string");
func(std::move(s)); // move the string
func(std::string("string")); // this is an rvalue and it is fine
}
关于通用引用的完整解释可以在这里找到:https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
相关文章:
- 非类型引用形参/实参
- 将右值引用形参强制转换为右值引用
- 给引用形参赋值使对象无效
- 是否有必要在定义中使用模板形参来引用同一个类?
- 指向成员变量的引用/指针作为模板形参
- 修改const形参引用
- 为什么模板非类型形参指针和引用实参需要是全局的
- 右值或左值(const)引用形参
- 将所有引用形参设为const的理由是什么?
- 我可以重用右值引用形参来返回右值引用吗?
- const引用形参的默认值
- map带有const模板形参和const引用模板形参
- 为什么c++中通过引用传递的形参不需要解引用操作符
- NULL直接传递给需要const引用形参的函数(vc++ 4.2)
- c++引用形参函数
- 函数引用形参的默认值
- 将函数输出直接传递给接受引用形参的函数
- 避免非const引用形参
- 如何访问const引用形参的值
- 可以基于引用形参类型重载构造函数吗?