I upgraded to the latest release of Google Test, and several of my tests no longer compiled. I've reduced it to this:
#include <gtest/gtest.h>
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
int main () {
const std::string foo = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const auto uppers = std::count_if(foo.begin(), foo.end(), std::isupper);
std::cout << "There are " << uppers << " capitals." << std::endl;
return 0;
}
The Visual Studio 2019 (16.10.4) compiler with /std:c++latest
complains:
1>Source.cpp(10,30): error C2672: 'std::count_if': no matching overloaded function found
1>Source.cpp(10,75): error C2780: 'conditional_t<std::_Is_from_primary<std::iterator_traits<remove_cv<remove_reference<_Ty2>::type>::type>>,std::incrementable_traits<remove_cv<remove_reference<_Ty2>::type>::type>,std::iterator_traits<remove_cv<remove_reference<_Ty2>::type>::type>>::difference_type std::count_if(_ExPo &&,const _FwdIt,const _FwdIt,_Pr) noexcept': expects 4 arguments - 3 provided
1>algorithm(570): message : see declaration of 'std::count_if'
1>Source.cpp(10,30): error C2783: 'conditional_t<std::_Is_from_primary<std::iterator_traits<remove_cv<remove_reference<_Ty>::type>::type>>,std::incrementable_traits<remove_cv<remove_reference<_Ty>::type>::type>,std::iterator_traits<remove_cv<remove_reference<_Ty>::type>::type>>::difference_type std::count_if(_InIt,_InIt,_Pr)': could not deduce template argument for '_Pr'
1>algorithm(553): message : see declaration of 'std::count_if'
If I comment out the inclusion of gtest.h, the code builds and executes correctly.
What could gtest.h be doing that messes up template argument deduction for a call that depends only on std
-defined types and functions?
[Note, my question is not how to workaround the problem, but to understand the specific underlying cause. I have a workaround: Replace the std::isupper
with a lambda.]
<locale>
, which introducestemplate< class charT > bool isupper( charT ch, const locale& loc )
which meansstd::isupper
is "now" overloaded and can't resolved. Does it work if you useconst auto uppers = std::count_if(foo.begin(), foo.end(), []()(auto ch){ return std::isupper(static_cast<unsigned char>(ch));} )
instead? – Plunge<gtest/gtest.h>
with<locale>
. I think that's the answer, as you can see in CPPreference thatstd::isupper
is overloaded in different header files. – Typologystd::isupper
as a generic classifier--a sortfoo
function that returnsbool
. I completely forgot about the nonsense that<locale>
brings in, and I hadn't expected Google Test to sneak it in. If you post an answer, the points are yours. Thanks also to @JDługosz for the verification tip! – Jenisejenkel