首页 文章

如何让自定义运营商==使用Google Test?

提问于
浏览
5

我在使用PCL和Google Test(GTest)的自定义重载'=='运算符时遇到问题

#include <pcl/point_types.h>
namespace pcl { struct PointXYZ; }

bool operator==(pcl::PointXYZ p1, pcl::PointXYZ p2) {return p1.x-p2.x<.1;}
#include <gtest/gtest.h>

TEST(Foo, bar) {
  pcl::PointXYZ a{2,3,4};
  pcl::PointXYZP b{2,3,4};
  EXPECT_EQ(a,b); // Compile error no match for operator==
}

int main(int argc, char **argv){
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

我得到的错误是:

|| /usr/include/gtest/gtest.h: In instantiation of 'testing::AssertionResult testing::internal::CmpHelperEQ(const char*, const char*, const T1&, const T2&) [with T1 = pcl::PointXYZ; T2 = pcl::PointXYZ]':
/usr/include/gtest/gtest.h|1361 col 23| required from 'static testing::AssertionResult testing::internal::EqHelper<lhs_is_null_literal>::Compare(const char*, const char*, const T1&, const T2&) [with T1 = pcl::PointXYZ; T2 = pcl::PointXYZ; bool lhs_is_null_literal = false]'
src/foo/src/tests.cpp|20 col 3| required from here
/usr/include/gtest/gtest.h|1325 col 16| error: no match for 'operator==' (operand types are 'const pcl::PointXYZ' and 'const pcl::PointXYZ')
||    if (expected == actual) {
||                 ^
/usr/include/gtest/internal/gtest-linked_ptr.h|213 col 6| note: candidate: template<class T> bool testing::internal::operator==(T*, const testing::internal::linked_ptr<T>&)
||  bool operator==(T* ptr, const linked_ptr<T>& x) {
||       ^
/usr/include/gtest/internal/gtest-linked_ptr.h|213 col 6| note:   template argument deduction/substitution failed:
/usr/include/gtest/gtest.h|1325 col 16| note:   mismatched types 'T*' and 'pcl::PointXYZ'

我试着坚持底漆:https://github.com/google/googletest/blob/master/googletest/docs/primer.md#binary-comparison

特别是,我的运算符在包含gtest之前定义,我确定类型匹配 . 我也尝试编写重载来获取const引用,但这只是比较了地址而不是值 .

2 回答

  • 12

    通过参数依赖查找找到自定义类型的运算符 .

    依赖于参数的查找(简而言之)意味着如果函数在与其一个或多个参数相同的命名空间中定义,则可以考虑这些函数 .

    这段代码:

    namespace pcl { struct PointXYZ; }
    
    bool operator==(pcl::PointXYZ p1, pcl::PointXYZ p2) {return p1.x-p2.x<.1;}
    

    pcl:: 名称空间中定义 PointXYZ ,但在全局名称空间中定义 operator== 函数 . 因此, not 是ADL的候选人 .

    这样做:

    namespace pcl { 
      struct PointXYZ; 
      bool operator==(pcl::PointXYZ p1, pcl::PointXYZ p2) {return p1.x-p2.x<.1;}
    }
    

    修复了因为现在运算符==的名称 pcl::operator== 与其参数之一在同一名称空间中(实际上在这种情况下都是这两个,但你明白了) . 这使它成为ADL期间的候选者,因此当gtest调用相等性测试时将选择它 .

  • 1

    namespace pcl 中包含 operator== 定义:

    #include <pcl/point_types.h>
    namespace pcl
    {
        bool operator==(pcl::PointXYZ p1, pcl::PointXYZ p2) {return p1.x-p2.x<.1;}
    }
    

    此外,您可以删除 pcl::PointXYZ 的前向声明,因为它必须在 Headers pcl/point_types.h 中完成 . 否则,编译器会在 TEST 中定义变量时抱怨 .

    如果未定义,您还必须定义 operator<<(std::ostream&, const pcl::PointXYZ&) ,以便Google Test可以在相等断言失败时打印出您的值 .

相关问题