如何改变boost :: variant运算符的行为<

时间:2015-02-06 17:54:27

标签: c++ boost operator-overloading boost-variant

boost :: variant定义运算符<如下:

  

if which()== rhs.which()then:content_this< content_rhs,在哪里   content_this是* this的内容,content_rhs是内容   RHS。否则:哪个()< rhs.which()。

这不是我想要的,因为我想失败一些<比较。例如,如果我有这样的变体:

typedef boost::variant<int, double, std::string> DataType;

我想要DataType(1)&lt; DataType(2.0)成功但DataType(1)&lt; DataType(“2”)抛出异常。有没有办法实现这个目标?

我无法定义

bool operator < (const Field& lhs, const Field& rhs)

因为它会与成员运营商冲突&lt;在变体类中定义。

我可以定义一个static_visitor,但我想知道是否还有重载运算符&lt;。

2 个答案:

答案 0 :(得分:1)

创建一个只包含struct的{​​{1}}。将构造函数转发给它(可能是一些手动)。提供boost::variant<Ts...> v;可选。

在此operator boost::variant<Ts...>()上拥有您自己的<

但请注意,struct旨在规范联合。它应该是 normal ,有些boost::variant是一种类型,有些是另一种类型。

variant通常位于<类型容器中或排序时。让密钥被强制为所有相同的类型,或者排序的元素都是相同的类型,似乎是一个坏主意。 std::map如果不希望任何此类variant包含这两种类型,则variant不应包含这两种类型。

自动使用<的地方都倾向于期望一个可选的排序谓词对象。我个人无法想到为什么我会手动使用异常抛出谓词对象,这让我对使你的默认设置失败感到遗憾。

答案 1 :(得分:1)

虽然将DataType包装在另一个结构中肯定是最佳解决方案,但请记住,如果您需要快速而肮脏的修复,则可以使用:

namespace boost
{
template<>
bool DataType::operator<(const DataType &) const
{   
    // impl
}
}

在C ++ 11中,您应该能够避免使用namespace boost

请注意,除非所有TU在实际使用之前都看到此专业化,否则会破坏ODR。