如何包括gtest.h打破模板参数演绎std算法?



我升级到最新版本的Google Test,我的几个测试不再编译。我把它简化为:

#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;
}

Visual Studio 2019(16.10.4)编译器与/std:c++latest抱怨:

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'

如果我注释掉gtest.h的包含,代码将正确构建并执行。

gtest.h做了什么,只依赖于std定义的类型和函数调用的模板参数推导混乱?

注意,我的问题不是如何解决这个问题,而是要了解具体的潜在原因。我有一个解决方法:用lambda替换std::isupper。]

似乎<gtest/gtest.h>现在包括<locale>,它引入了

template< class charT > bool isupper( charT ch, const locale& loc ) 

放入作用域。这意味着std::isupper现在有两个可能的函数可以指向,如果不指定使用哪一个,就会出现歧义,导致模板参数推导失败。

如果您使用lambda路由来解决此问题,请确保将std::isupper的输入强制转换为unsigned char,如

const auto uppers = std::count_if(foo.begin(), 
                                  foo.end(), 
                                  []()(auto ch){ return std::isupper(static_cast<unsigned char>(ch));} )

相关内容

  • 没有找到相关文章

最新更新