如何改变 boost::variant operator < 的行为

How to change the behaviour of boost::variant operator <

boost::variant 定义 operator < 如下:

If which() == rhs.which() then: content_this < content_rhs, where content_this is the content of *this and content_rhs is the content of rhs. Otherwise: which() < rhs.which().

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

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

我希望 DataType(1) < DataType(2.0) 成功,但 DataType(1) < DataType("2") 抛出异常。有什么办法可以实现吗?

我无法定义

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

因为它会与变体class.

中定义的成员运算符<冲突

我可以定义一个 static_visitor,但我想知道是否有重载运算符 <.

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

在这个 struct 上有你自己的 <

但是请注意,boost::variant 旨在使联合正常化。应该是正常有的variant是一种,有的是另一种

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

自动使用<的地方都倾向于期望一个可选的排序谓词对象。我个人想不出为什么我会手动使用异常抛出谓词对象,这让我对将你的对象设为默认值持怀疑态度。

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

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

在 C++11 中你应该能够避免 namespace boost.

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