如何在std::variant中正确调用自定义类的赋值运算符
问题:std::variant无法调用自定义类的std::string赋值运算符
完整示例代码:
#include <string> #include <variant> class StackStringHolder { public: StackStringHolder& operator=(const std::string& str) { str_ = str; return *this; } StackStringHolder& operator=(std::string&& str) { str_ = std::move(str); return *this; } const std::string& get() const { return str_; } private: std::string str_; }; int main() { std::variant<int, StackStringHolder> var; var = 5; std::string str = "Hello"; var = str; // error var = std::move(str); // error return 0; }
使用MSVS2022编译时出现如下错误:
error C2679: binary '=': no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)
解决方案
方案1:为StackStringHolder添加隐式转换构造函数
给StackStringHolder添加接受std::string的构造函数,让编译器可以自动将std::string转换为StackStringHolder类型,适配std::variant的赋值逻辑:
class StackStringHolder { public: // 添加这两个构造函数 StackStringHolder(const std::string& str) : str_(str) {} StackStringHolder(std::string&& str) : str_(std::move(str)) {} StackStringHolder& operator=(const std::string& str) { str_ = str; return *this; } StackStringHolder& operator=(std::string&& str) { str_ = std::move(str); return *this; } const std::string& get() const { return str_; } private: std::string str_; };
修改后,原代码中的var = str;和var = std::move(str);即可正常编译。
方案2:显式构造StackStringHolder对象赋值
如果不想修改StackStringHolder类,可以显式构造对象后再赋值给std::variant:
int main() { std::variant<int, StackStringHolder> var; var = 5; std::string str = "Hello"; var = StackStringHolder(str); // 显式构造 var = StackStringHolder(std::move(str)); // 显式移动构造 return 0; }
原因说明
std::variant的赋值运算符要求右操作数要么是其备选类型之一,要么能隐式转换为某个备选类型。你的StackStringHolder虽然实现了接受std::string的赋值运算符,但没有对应的构造函数,编译器无法自动将std::string转换为StackStringHolder实例,因此无法完成variant的赋值操作。
内容的提问来源于stack exchange,提问作者qloq
相关产品推荐
相关产品推荐

