c++ - std::forward 和带有非常量引用参数的构造函数

标签 c++ c++11 perfect-forwarding

右值引用简介中,提出了完美转发作为将右值 5 转发到具有非常量引用参数的构造函数的理想解决方案。

但是:

#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);
}

在 XCode 4.2 和 G++ 4.6.1 中失败,没有已知的从 int 到 int& 的转换,而:

template <class T, class A1>
std::shared_ptr<T> factory(A1&& a1) {
   return std::shared_ptr<T>(new T(/*no forwarding*/a1));
}

编译。我做错了什么?

最佳答案

您不能将右值绑定(bind)到非常量左值引用。文章不建议为此使用完美转发,因为那是不可能的。完美转发将左值转发为左值,将右值转发为右值:

Here, forward preserves the lvalue/rvalue-ness of the argument that was passed to factory. If an rvalue is passed to factory, then an rvalue will be passed to T's constructor with the help of the forward function. Similarly, if an lvalue is passed to factory, it is forwarded to T's constructor as an lvalue.

由于您示例中的构造函数仅采用左值,因此您只能将左值传递给工厂函数。传递右值会将其作为右值转发,这将是格式错误的,因为无法将右值传递给该构造函数。

关于c++ - std::forward 和带有非常量引用参数的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8355317/

相关文章:

c++ - std::string::substr 返回的对象的生命周期

c++ - 虚函数声明和定义的困惑

c++ - 完美转发可变参数模板到标准线程

c++ - std::foward 的第二次重载(cppreference.com 上的示例)

c++ - 未定义的类,无法从 main 到达我的 header

c++ - 如何使用 Windows 可移植设备 C++ API 获取 MTP 设备公开的文件夹中所有文件(对象)的列表?

c++ - 在 OpenCV 中找到部分隐藏的球

c++ - 使用静态方法初始化 const 类字段是好事还是坏事?

c++ - C++ 中的内存仿函数包装器

c++ - `auto &&`参数可以完美转发吗?