std :: remove_if和std :: isspace - 编译时错误

时间:2014-02-05 13:21:41

标签: c++ gcc g++

我有以下代码:

#include <algorithm>
#include <cctype>
#include <string>

int main()
{
    std::string str;
    str.erase(std::remove_if(str.begin(), str.end(), std::isspace), str.end());
}

MSVC-11.0编译此代码时没有任何错误,但gcc 4.7.2给出了以下错误:

main.cpp: In function ‘int main()’:
main.cpp:8:66: error: no matching function for call to ‘remove_if(std::basic_string<char>::iterator, std::basic_string<char>::iterator, <unresolved overloaded function type>)’
main.cpp:8:66: note: candidate is:
In file included from /usr/include/c++/4.7/algorithm:63:0,
                 from main.cpp:1:
/usr/include/c++/4.7/bits/stl_algo.h:1160:5: note: template<class _FIter, class _Predicate> _FIter std::remove_if(_FIter, _FIter, _Predicate)
/usr/include/c++/4.7/bits/stl_algo.h:1160:5: note:   template argument deduction/substitution failed:
main.cpp:8:66: note:   couldn't deduce template parameter ‘_Predicate’

我发现this有关它的问题,但根据cppreference,这个函数没有任何版本带有两个参数。我也发现了this的问题,但根据cppreference(是的,再次),我看到只有一个std :: isspace函数重载。

谁是对的?我究竟做错了什么?我该如何解决?

3 个答案:

答案 0 :(得分:13)

another overload of std::isspace,因此您需要指定使用哪一个。一个简单的方法是使用lambda(或者如果你没有C ++ 11支持,可以编写自己的单行函数):

std::remove_if(str.begin(), str.end(), 
               [](char c){ 
                  return std::isspace(static_cast<unsigned char>(c));
               });

答案 1 :(得分:5)

std::isspace是一个重载函数,尽管两个重载位于不同的头文件中。另请注意,您的代码可能会引入未定义的行为,因为只有0..UCHAR_MAX范围内的值可以传递给std::isspace,而char可能会签名。

这是一个解决方案:

std::string str;
auto f = [](unsigned char const c) { return std::isspace(c); };
str.erase(std::remove_if(str.begin(), str.end(), f), str.end());

答案 2 :(得分:0)

以下解决方案应该可以帮助您解决编译时错误:

str.erase(std::remove_if(str.begin(), str.end(), (int(*) (int)) std::isspace), str.end());