Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a custom operator== to work with Google Test?

I'm having trouble using a custom overloaded '==' operator with PCL and 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();
}

The error I get is:

|| /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'

I tried to adhere to the primer: https://github.com/google/googletest/blob/master/googletest/docs/primer.md#binary-comparison

In particular, my operator is defined before including gtest, and I'm sure the types match up. I also tried writing the overload to take const references, but that just compared the addresses instead of the values.

like image 605
Andrew Wagner Avatar asked Oct 27 '15 14:10

Andrew Wagner


People also ask

How do I add a Google Test to a C++ project?

Add a Google Test project in Visual Studio 2022In Solution Explorer, right-click on the solution node and choose Add > New Project. Set Language to C++ and type test in the search box. From the results list, choose Google Test Project. Give the test project a name and choose OK.

How do I link a Google project to a test?

Adding Google Test to your project txt file inside the Google_tests folder: right-click it in the project tree and select New | CMakeLists. txt. In your root CMakeLists. txt script, add the add_subdirectory(Google_tests) command to the end, then reload the project.


2 Answers

Operators on custom types are found through argument dependent lookup.

Argument dependent lookup (in a nutshell) means that functions may be considered if they are defined in the same namespace as one or more of their arguments.

This code:

namespace pcl { struct PointXYZ; }

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

defines PointXYZ in the pcl:: namespace, but defines the operator== function in the global namespace. Hence, not a candidate for ADL.

doing this:

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

Fixes that because now the operator== has the name pcl::operator== which is in the same namespace as one of its arguments (actually in this case both of them, but you get the idea). This makes it a candidate during ADL and thus it will be selected when gtest invokes the equality test.

like image 192
Richard Hodges Avatar answered Oct 05 '22 12:10

Richard Hodges


Include the operator== definition within the namespace pcl:

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

Besides, you can remove the forward declaration for pcl::PointXYZ since it must be complete in header pcl/point_types.h. Otherwise, compiler would complain when defining variables within TEST.

If not defined, you will also have to define operator<<(std::ostream&, const pcl::PointXYZ&) so that Google Test can print out your values when the equality assertion fails.

like image 26
Antonio Pérez Avatar answered Oct 05 '22 12:10

Antonio Pérez