10

Here's the code:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    string word="";
    getline(cin,word);
    word.erase(remove_if(word.begin(), word.end(), isspace), word.end()); 
    word.erase(remove_if(word.begin(), word.end(), ispunct), word.end()); 
    word.erase(remove_if(word.begin(), word.end(), isdigit), word.end());
}

When compiled in VS 2010, it works perfectly fine. Compiled with G++ it says:

hw4pr3.cpp: In function `int main()':
hw4pr3.cpp:20: error: no matching function for call to `remove_if(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unknown type>)'
hw4pr3.cpp:21: error: no matching function for call to `remove_if(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unknown type>)'
hw4pr3.cpp:22: error: no matching function for call to `remove_if(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unknown type>)'
ruakh
  • 175,680
  • 26
  • 273
  • 307
Richard
  • 5,840
  • 36
  • 123
  • 208

4 Answers4

23

Add :: to the beginning of isspace, ispunct and isdigit, since they have overloads that the compiler can't decide on which to use:

word.erase(remove_if(word.begin(), word.end(), ::isspace), word.end()); 
word.erase(remove_if(word.begin(), word.end(), ::ispunct), word.end()); 
word.erase(remove_if(word.begin(), word.end(), ::isdigit), word.end());
AusCBloke
  • 18,014
  • 6
  • 40
  • 44
  • At best having C library functions in the global namespace is deprecated and legacy (you would have to include ``), and at worst its just an odd compiler peculiarity that shouldn't be relied upon. – Kerrek SB Dec 03 '11 at 01:26
  • @KerrekSB: I didn't realise it was deprecated/hacky, thanks for the tip. – AusCBloke Dec 03 '11 at 01:31
4

Add #include <cctype> (and say std::isspace etc. if you aren't abusing namespace std;).

Always include all headers that you need, and don't rely on hidden nested inclusions.

You may also have to disambiguate the overload from the other one in <locale>. Do this by adding an explicit cast:

word.erase(std::remove_if(word.begin(), word.end(),
                          static_cast<int(&)(int)>(std::isspace)),
           word.end());
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
2

For me it compiles using g++ if I do either of the following:

  • remove using namespace std; and change string to std::string; or
  • change isspace to ::isspace (etc.).

Either of these will cause isspace (etc.) to be taken from the main namespace, instead of being interpreted as possibly meaning std::isspace (etc.).

ruakh
  • 175,680
  • 26
  • 273
  • 307
1

The problem is that std::isspace(int) takes an int as a parameter but a string is composed of char. So you have to write your own function as:

bool isspace(char c) { return c == ' '; }

The same applies to the other two functions.

memecs
  • 7,196
  • 7
  • 34
  • 49