用 boost::variant 元素填充的 std::set 不能按后代排序?

Posted

技术标签:

【中文标题】用 boost::variant 元素填充的 std::set 不能按后代排序?【英文标题】:std::set filled with boost::variant elements cannot be sorted descendantly? 【发布时间】:2009-04-14 19:57:25 【问题描述】:
typedef boost::variant<long long,double,string> possibleTypes ;

set<possibleTypes,less<possibleTypes> > ascSet ;
set<possibleTypes,greater<possibleTypes> > descSet ;

当我尝试编译时,我在一些库头文件中遇到了一堆错误。 但是,如果我删除第三行(带有 descSet 的那一行),代码编译就好了。

有什么问题? boost::variant 对象不能按后代顺序排序吗??

编辑: 我正在使用 Visual Studio 2005 和 Boost 1.38.0 以及以下命令行:

cl /EHsc /I"C:\boost_1_38_0" test.cpp

编辑2 正如 Doug T 所建议的那样,如果我定义这个:

bool operator>(const possibleTypes& a, const possibleTypes& b)
   return b < a ;

那么下面的代码不会编译:

possibleTypes pt1="a", pt2="b" ;
greater<possibleTypes> func ;   
cout << func(pt1,pt2) << endl ;

但是,这段代码编译得很好:

possibleTypes pt1="a", pt2="b" ;
cout << (pt1 > pt2) << endl ;

谁能帮我理解为什么?

我尝试使用 VC++ 2005 和 GCC 3.4.6

【问题讨论】:

您使用的是哪个版本的 Boost?我刚刚用 1.38.0 和 VC++ 9.0 尝试了你的代码,它编译没有任何问题。 为什么要有两套?当您需要降序时,为什么不只使用一个并使用反向迭代器? 真的吗?一定是编译器版本(我刚刚更新了我的帖子) 你能提供至少第一个错误信息吗? IE。关于声明本身的声明,而不是由于 descSet 定义不正确而导致的声明。 【参考方案1】:

似乎为 boost::variant 定义了 运算符定义。因此,也许 std::less 有效,但 std::greater

无效

见here

我会尝试定义一个免费的 > 运算符。

bool operator > (boost::variant<...> lhs, boost::variant<..> rhs)

    return (rhs < lhs) // thanks Chris Jester Young

【讨论】:

为什么不只是:返回 rhs 是的,这样会更简单,不是吗:)【参考方案2】:

您需要有更大的运算符可用。如果 possibleTypes 没有提供,您可以像 Doug 建议的那样定义一个免费的,或者尝试使用Boost operators。

【讨论】:

【参考方案3】:

按照建议,如果我这样定义:

bool operator>(const possibleTypes& a, const possibleTypes& b)
   return b < a ;

那么下面的代码不会编译:

possibleTypes pt1="a", pt2="b" ;
greater<possibleTypes> func ;   
cout << func(pt1,pt2) << endl ;

但是,这段代码编译得很好:

possibleTypes pt1="a", pt2="b" ;
cout << (pt1 > pt2) << endl ;

谁能帮我理解为什么?

我尝试使用 VC++ 2005 和 GCC 3.4.6

【讨论】:

尝试在命名空间 boost 中定义 operator>:命名空间 boost bool operator>(const possibleTypes& a, const possibleTypes& b) ... 。编译器为 operator> 寻找错误的位置,尽管我个人希望它查看任何 operator> 采用两个可能的类型参数。 否 - 依赖于参数的查找。它不会到处搜索,它会在调用者的命名空间 (std::greater) 和参数的命名空间 (boost::variant) 中查找。在第二种情况下,调用者的命名空间(可能)是全局命名空间。 谢谢,马克斯。问题已修复,将 operator> 添加到 boost 命名空间。感谢 MSalters 澄清规则。

以上是关于用 boost::variant 元素填充的 std::set 不能按后代排序?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能用 boost::variant 访问这个自定义类型?

如何将项目从 boost::variant 移动到多地图?

将由 boost::variant 聚合的类型的对象传递给接受该 boost::variant 的函数

如何返回由 boost::variant 返回类型中包含的类型的子集组成的 boost::variant

Boost::Variant 和其中的 function_types:如何将函数放入 Boost::variant?

boost::variant:递归向量类型的奇怪行为