结构的泛型比较运算符
Generic comparison operator for structs
在我的许多单元测试中,我需要比较只有数据成员的简单结构的内容:
struct Object {
int start;
int stop;
std::string message;
}
现在,如果我想写这样的东西:
CHECK(object1==object2);
我总是必须实现:
bool operator==(const Object& lhs, const Object& rhs) {
return lhs.start==rhs.start && lhs.stop==rhs.stop && lhs.message=rhs.message;
}
编写所有这些比较函数变得乏味,但也容易出错。试想一下,如果我向 Object 添加新的数据成员,但比较运算符不会更新,会发生什么。
然后我想起了我在 Haskell 和魔术deriving(Eq)
指令中的知识,它只是免费生成一个理智的比较函数。
怎么,我能在C++中得出类似的东西?
令人高兴的是,我发现 C++17 带有一个通用operator==
,并且每个结构都应该很容易转换为std::tuple
借助std::make_tuple
.
所以我大胆地尝试了以下几点:
#include <tuple>
#include <iostream>
#include <tuple>
template<typename T>
bool operator==(const T& lhs, const T& rhs)
{
auto leftTuple = std::make_tuple(lhs);
auto rightTuple = std::make_tuple(rhs);
return leftTuple==rightTuple;
}
struct Object
{
std::string s;
int i;
double d;
};
int main(int arg, char** args)
{
std::cout << (Object{ "H",1,2. } == Object{ "H",1,2. }) << std::endl;
std::cout << (Object{ "A",2,3. } == Object{ "H",1,2. }) << std::endl;
return EXIT_SUCCESS;
}
但是,不幸的是,它只是无法编译,我真的不知道为什么。叮当告诉我:
main.cpp:11:18: error: use of overloaded operator '==' is ambiguous (with operand types
'std::tuple<Object>' and 'std::tuple<Object>')
return leftTuple==rightTuple;
我可以修复此编译错误以获得我想要的行为吗?
不,因为比较元组恢复为比较元组的元素,所以leftTuple == rightTuple
尝试比较两个Object
,这是不可能的。
每个结构都应该很容易转换为
,因为std::tuple
std::make_tuple
不,你只会得到一个带有一个元素的tuple
,即结构。
诀窍是使用std::tie
:
std::tie(lhs.mem1, lhs.mem2) == std::tie(rhs.mem1, rhs.mem2)
但这与您的原始解决方案具有相同的问题。不幸的是,C++17 没有任何工具来避免这个问题,您可以编写宏:)。但是在 C++20 中,您将能够做到:
struct Object
{
std::string s;
int i;
double d;
bool operator==(const Object &) const = default;
};
这将为Object
生成正确的比较运算符。
相关文章:
- 为什么比较运算符如此快速
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 关于 std::min, std::max 中的比较运算符的混淆
- 三向比较运算符成员与非成员实现
- 标准::可选枚举的比较运算符
- 为什么字符串比较的 == 运算符相对于任一字符串长度线性时间(似乎)?
- C++分数混合比较运算符错误
- <<运算符优先级与字符串比较
- 不能将重载比较运算符与 Catch 测试一起使用
- 重构使用动态强制转换的 std::set 的比较运算符
- ">"运算符和"<"运算符如何进行字符串比较?
- "operator()"在重载运算符方法中是什么意思,在priority_queue(STL)中用作C++中的比较器?
- C++使用关系运算符比较字符串
- 为什么使用 and 运算符比较 if 语句中的 2 个对象会抛出错误,而使用 2 if 语句则不会
- 使用关系运算符比较指针意味着什么
- 运算符<比较多个字段
- 运算符==比较两个不同的类
- 使用==运算符比较字符串到0
- 使用'if'语句和"<<"时的结果错误,'>>'运算符比较 3 个整数