为不可拷贝不可移动类实现可移动包装器时的std::forward调用错误
问题分析与解决
嘿,这个问题其实很常见——你在使用std::forward的时候犯了一个小错误!
错误原因
你写的std::forward(args)...是不正确的用法:std::forward是一个模板函数,必须显式指定它的模板参数,编译器才能正确识别需要转发的参数的左值/右值属性。如果省略模板参数,编译器无法推导_Tp类型,就会抛出你看到的“无法推导模板参数‘_Tp’”的错误。
修正方案
只需要把构造函数里的std::forward(args)...改成std::forward<Args>(args)...,就能完美解决问题。这里的Args是模板参数包,它会保留原始参数的类型信息(包括左值/右值引用属性),让std::forward正确完成转发。
修正后的完整代码
#include <iostream> #include <memory> #include <string> #include <utility> struct X { std::string x; X(const std::string &x) : x(x) {} X(const X &x) = delete; X(X &&x) = delete; }; struct Wrapper { std::unique_ptr<X> x; Wrapper(const Wrapper & wrapper) = delete; Wrapper(Wrapper && wrapper) = default; template<typename... Args> Wrapper(Args&&... args) : x(std::make_unique<X>(std::forward<Args>(args)...)) {} }; int main() { const std::string XXX = "XXX"; Wrapper w{XXX}; std::cout << w.x->x << std::endl; }
补充说明
当你传入const std::string&类型的参数时,模板参数Args会被推导为const std::string&,std::forward<Args>(args)会保留这个左值引用属性,正好匹配X类中定义的const std::string&构造函数,从而成功创建X的实例并放入unique_ptr中。
内容的提问来源于stack exchange,提问作者Erbureth
相关产品推荐
相关产品推荐

