C++ Boost变量引用与等式比较
以下程序中止:C++ Boost变量引用与等式比较,c++,boost,boost-variant,C++,Boost,Boost Variant,以下程序中止: #include <boost/variant.hpp> using variant_type = boost::variant< int&, std::string& >; int main () { int a, b; variant_type v (a), u (b); v == u; return 0; } 因为在类known_get中选择了错误的运算符函数调用重载,所以不能比较非常量引用变
#include <boost/variant.hpp>
using variant_type = boost::variant< int&, std::string& >;
int main () {
int a, b;
variant_type v (a), u (b);
v == u;
return 0;
}
因为在类known_get中选择了错误的运算符函数调用重载,所以不能比较非常量引用变量之间的相等性。known_get在comparer visitor中被实例化为const T,而不是看起来应该是T的内容(v1.59.0中的variant.hpp:905)
我遗漏了什么吗?好的,我对此进行了思考(并再次查看了文档) boost::variant的概要没有显示为变量定义的运算符== 这使我认为正确的比较方法是通过二进制访问者 这是你的(修改过的)代码,它在我的机器上编译(苹果叮当声)。你的代码也使我的编译器崩溃了
#include <string>
#include <boost/variant.hpp>
using variant_type = boost::variant< int&, std::string& >;
struct is_equal
{
// compare int with int
bool operator()(const int& l, const int& r) const {
return l == r;
}
// compare string with string
bool operator()(const std::string& l, const std::string& r) const {
return l == r;
}
// anything else compared with anything else compares false.
template<class X, class Y>
bool operator()(const X&, const Y&) const {
return false;
}
};
int main () {
int a = 0, b = 0;
variant_type v = a, u = b;
bool ok = boost::apply_visitor(is_equal(), v, u);
// bool ok = (v == u);
return 0;
}
#包括
#包括
使用variant_type=boost::variant;
结构是相等的
{
//比较int与int
布尔运算符(){
返回l==r;
}
//将字符串与字符串进行比较
布尔运算符()(常数std::string&l,常数std::string&r)常数{
返回l==r;
}
//其他任何东西与其他任何东西相比都是假的。
模板
布尔运算符()(常数X&,常数Y&)常数{
返回false;
}
};
int main(){
int a=0,b=0;
变量类型v=a,u=b;
bool ok=boost::apply_visitor(is_equal(),v,u);
//布尔ok=(v==u);
返回0;
}
我认为这是一个Boost bug
以下是:
- 可复制的或可移动的李>
- 析构函数支持无抛出异常安全保证
- 在变量模板实例化点完成。(有关接受不完整类型以启用递归变量类型的类型包装,请参见
)boost::recursive_wrapper
- EqualityComparable:
本身是EqualityComparable的,当且仅当其每一个有界类型都满足概念的要求时variant
template <typename T>
bool operator()(const T& rhs_content) const
{
// Since the precondition ensures lhs and rhs types are same, get T...
known_get<const T> getter;
const T& lhs_content = lhs_.apply_visitor(getter);
// ...and compare lhs and rhs contents:
return Comp()(lhs_content, rhs_content);
}
使用int&
,这些重载将变成:
const int& operator()(const int& ) const;
const int& operator()(int& ) const; [ U = int ]
第二个重载是首选的,因为它引用的类型比非模板重载的const-qualified更少。这就是为什么您会得到断言,而这种行为显然是不正确的。我们应该能够比较参考资料
更简单的解决方案是从比较器
中删除常量
s,只需使用:
template <typename T>
bool operator()(T& rhs_content) const
{
known_get<T> getter;
T& lhs_content = lhs_.apply_visitor(getter);
return Comp()(lhs_content, rhs_content);
}
模板
布尔运算符()(T&rhs_内容)常量
{
已知的获得者;
T&lhs\u content=lhs\u.apply\u访问者(getter);
返回Comp()(左侧内容、右侧内容);
}
这将适用于引用类型以及
const
类型 我在boost文档中看不到任何关于引用变体的信息。那么乌布?我不这么认为。虽然docs和esp是真的。教程中没有提到存储引用,但使用这些引用的变体似乎没有任何障碍。Richard,在variant.hpp标头的第2236行定义了一个运算符==。如果那个操作员不在,我也会实施你的解决方案。现在我把这个失败归因于一个可能的错误,因为如果在variant.hpp的第905行将const T更改为known_get的模板参数列表中的T,代码编译并运行正常。同意如果操作符==应该是公共接口的一部分,那么它看起来就像一个错误。令人惊讶的是,它同时使clang和gcc崩溃:)是的,我的担心是我遗漏了一些明显的东西,关于为什么known_get被实例化为const T而不是T。我将尝试用boost提交一个bug,然后返回投票。
const int& operator()(const int& ) const;
const int& operator()(int& ) const; [ U = int ]
template <typename T>
bool operator()(T& rhs_content) const
{
known_get<T> getter;
T& lhs_content = lhs_.apply_visitor(getter);
return Comp()(lhs_content, rhs_content);
}