如何正确使用std::forward?排查无法用std::string实例化类的问题
关于std::forward的正确用法及你的代码错误分析
你的代码中的错误点
- 参数名冲突+初始化逻辑错误:
const char *MyClass的参数名和类名重复,且初始化列表str(str)里的str未定义(参数名是MyClass而非str),这会直接导致编译失败。 - 模板构造函数匹配范围受限:模板构造函数的参数是
Type &str(左值引用),无法接收临时std::string对象(右值),也无法匹配const std::string类型的左值。 - std::forward误用:std::forward的核心作用是完美转发,仅适用于**转发引用(Type&&,且Type为推导得到的模板参数)**场景。你的模板参数是左值引用类型,这里使用std::forward没有意义,属于用法错误。
修正后的代码示例
#include <string> #include <type_traits> class MyClass { public: MyClass() noexcept = default; MyClass(MyClass &&) noexcept = default; MyClass(const MyClass &) noexcept = default; MyClass &operator=(MyClass &&) noexcept = default; MyClass &operator=(const MyClass &) noexcept = default; // 修正const char*构造函数的参数名和初始化逻辑 MyClass(const char *cstr) noexcept : str(cstr) { } // 使用转发引用实现完美转发,同时限制类型为std::string及其cv变种 template <typename Type> requires std::is_same_v<std::decay_t<Type>, std::string> MyClass(Type &&str) noexcept : str(std::forward<Type>(str)) { } private: std::string str; };
std::forward的正确使用场景
std::forward用于在模板函数中保留原始参数的值类别(左值/右值),必须配合**转发引用(模板参数为Type&&,且Type是推导得到的模板参数)**使用:
- 传入左值时,Type会被推导为左值引用类型,std::forward
(param)会转发为左值。 - 传入右值时,Type会被推导为非引用类型,std::forward
(param)会转发为右值。
典型完美转发场景示例:
template <typename T> void wrapper(T &&arg) { func(std::forward<T>(arg)); // 完美转发arg的原始值类别给func }
内容的提问来源于stack exchange,提问作者no one special
相关产品推荐
相关产品推荐

