在我的许多单元测试中,我需要比较仅具有数据成员的简单结构体的内容:
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::make_tuple
函数方便地转换为一个std::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;
}
但是,不幸的是,它只是无法编译,我真的不知道为什么。Clang告诉我:
main.cpp:11:18: error: use of overloaded operator '==' is ambiguous (with operand types
'std::tuple<Object>' and 'std::tuple<Object>')
return leftTuple==rightTuple;
我是否能够修复这个编译错误,以获得我想要的行为?