在特殊情况下
我有一个数据结构
namespace x3 = boost::spirit::x3;
struct one;
struct two : x3::variant<x3::forward_ast<one>,int>{
using base_type::base_type;
using base_type::operator=;
two& operator=(const std::string& rhs){
return *this;
}
two& operator=(const std::string&& rhs){
return *this;
}
};
struct one : x3::variant<boost::recursive_wrapper<two>,std::string>{
using base_type::base_type;
using base_type::operator=;
};
在这种情况下,分配是可以的
one on{"sssss"};
two wo{22};
wo = 123;
on = std::string("vvvvvvvvvvv");
on = wo;
但是当我直接将一个字符串赋给wo时,它会提示一个错误:
wo = on;
// wo = one("sadfasdfas"); //You can't do this
wo = std::string("sadfasdfas"); <----【/usr/local/include/boost/variant/variant.hpp:2172:14: Candidate function not viable: no known conversion from 'std::string' to 'boost::variant<boost::spirit::x3::forward_ast<one>, int>' for 1st argument】
我已经重载了相关函数,但似乎没有效果。谁知道这是为什么,并告诉我如何作出正确的修改
1条答案
按热度按时间tgabmvqs1#
问题是,您为
const std::string&
和const std::string&&
重载了two::operator=
,这两个都不是使用(非常量)右值参数std::string("vvvvvvvvvvv")
进行重载解决的最佳匹配。相反,最佳匹配来自using base_type::operator=
中包含的x3::variant::operator=(T&&)
(source):行
var = std::forward<T>(rhs);
导致了你提到的编译错误(var
是不能赋值字符串的boost::variant<boost::spirit::x3::forward_ast<one>, int>
)。为了让你的重载像预期的那样工作,你可以让你的右值赋值操作符接受非常量的右值引用,使它在重载解析中比模板化的
operator=
具有更高的优先级(并且实际上使它能够充分实现,因为你无论如何都不能从const std::string&&
移动):(godbolt)
请注意,您不需要在
one
byboost::recursive_wrapper
中第二次“打破继承周期”,它可以被删除。此外,// wo = one("sadfasdfas");
也可以取消注解并按预期工作。