Kla*_*ens 7 c++ perfect-forwarding c++11
在Rvalue References的简介中,提出了完美转发作为将rvalue 5转发到具有非const引用参数的构造函数的理想解决方案.
但:
#include <memory>
#include <iostream>
#include <utility>
template <class T, class A1>
std::shared_ptr<T> factory(A1&& a1) {
return std::shared_ptr<T>(new T(std::forward<A1>(a1)));
}
class X {
public:
X(int& i){
std::cout<<"X("<<i<<")\n";
}
};
int main() {
std::shared_ptr<X> p = factory<X>(5);
}
Run Code Online (Sandbox Code Playgroud)
在XCode 4.2和G ++ 4.6.1中失败no known conversion from int to int&,而:
template <class T, class A1>
std::shared_ptr<T> factory(A1&& a1) {
return std::shared_ptr<T>(new T(/*no forwarding*/a1));
}
Run Code Online (Sandbox Code Playgroud)
编译.我弄错了什么?
提出了完美转发作为将rvalue 5转发到具有非const引用参数的构造函数的理想解决方案.
我不认为完美转发意味着.如果这篇文章是正确的,这篇文章甚至不能暗示这一点.
相反,它意味着它可以将rvalue引用转发为rvalues,因此可以调用move-constructor或带有rvalue引用的构造函数/函数.
所以你应该试试这个:
class X {
public:
X(int& i){
std::cout<<"X("<<i<<")\n";
}
//this is a constructor which takes rvalue references
X(int&& i){
std::cout<<"X("<<i<<")\n";
}
};
Run Code Online (Sandbox Code Playgroud)
也就是说,factory应该调用第二个构造函数,而不是你编写的构造函数.
顺便说一下,在这种情况下,构造函数没有多大意义,因为参数类型int是基本类型.
Rvalue referencs作为参数类型用于定义管理资源的类的移动构造函数和移动分配.如果用户定义的类不管理资源,则移动语义没有意义.
您不能将rvalues绑定到非const左值引用.该文章并未建议使用完美转发,因为这是不可能的.完美转发左值作为左值,右值作为右值:
这里,forward保留传递给工厂的参数的左值/右值.如果将右值传递给工厂,则在前向函数的帮助下将右值传递给T的构造函数.类似地,如果将左值传递给工厂,它将作为左值转发给T的构造函数.
由于示例中的构造函数只接受左值,因此只能将左值传递给工厂函数.传递一个右值会将它作为一个右值转发,并且由于没有办法将右值传递给该构造函数,因此格式错误.