0

We have the following c++ code using catch2 framework:

auto check2 = [](size_t exp, size_t val, auto comp) {
    REQUIRE(comp(exp, val));
};
check2(10, 20, std::equal_to<size_t>{});

and clang-tidy generates the following

/test_lingua.cpp:1236:36: warning: prefer transparent functors 'equal_to<>' [modernize-use-transparent-functors]
check2(10, 20, std::equal_to<size_t>{});
               ^

Can any (reasonable) change to the code make clang-tidy happy?

UPDATE:

The original code compared size_t and nlohmann::json (something like REQUIRE(comp(val, exp_dict[s]));) and the problem using std::equal_to<>{} resulted in this compilation error

1>test_lingua.cpp(1224,25): error C2672: 'operator __surrogate_func': no matching overloaded function found
1>test_lingua.cpp(1227): message : see reference to function template instantiation 'void maz::tests::test_superscript_remover::<lambda_afa1c9ba8dd5ae9bea1ac934f5f796ab>::()::<lambda_9d6a94e643f0b9fe3677202d1edfa8f2>::operator ()<std::equal_to<void>>(const std::string &,size_t,std::equal_to<void>) const' being compiled
1>test_lingua.cpp(1224,1): error C2893: 
Failed to specialize function template 'unknown-type std::equal_to<void>::operator ()(_Ty1 &&,_Ty2 &&) noexcept(<expr>) const'
1>E:\VS019\VC\Tools\MSVC\14.29.30037\include\xstddef(198): message : see declaration of 'std::equal_to<void>::operator ()'

In order to fix this, you had to also use .get<size_t>() in order for the perfect forwarding to work.

  • Does `clang-tidy -fix ...` make an edit for this one? – aschepler Jan 04 '22 at 23:13
  • Sidenote: I would take the _modernization_ suggestions given by clang-tidy with a grain of salt. This one may be a good one but I wouldn't just obey them blindly. It suggests pointers where I personally think it's bonkers to not use references. – Ted Lyngmo Jan 04 '22 at 23:17
  • The warning proposes the suggestion: `std::equal_to` -> `std::equal_to<>`. – Jarod42 Jan 05 '22 at 10:35

1 Answers1

4

You simply replace

std::equal_to<size_t>{}

with

std::equal_to<>{}

(C++14 and above, uses template default argument) or

std::equal_to{}

(C++17 and above, uses CTAD).

This way the std::equal_to<void> specialization is used, which generically compares two arguments a and b of any types as if by a == b (plus perfect forwarding).

It avoids having to specify the correct types again, so you don't have to repeat yourself, which may sometimes be a source of error (e.g. if the types are changed but the std::equal_to template argument is not correctly updated).

user17732522
  • 53,019
  • 2
  • 56
  • 105