【问题标题】:g++ string remove_if errorg++字符串remove_if错误
【发布时间】:2011-12-03 01:13:50
【问题描述】:

代码如下:

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

在 VS 2010 中编译时,它工作得非常好。用 G++ 编译它说:

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>)'

【问题讨论】:

    标签: c++ string visual-studio-2010 g++ remove-if


    【解决方案1】:

    :: 添加到isspaceispunctisdigit 的开头,因为它们具有编译器无法决定使用哪个重载:

    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());
    

    【讨论】:

    • 在全局命名空间中最好有 C 库函数已被弃用和遗留(你必须包含 &lt;ctype.h&gt;),最坏的情况是它只是一个不应该依赖的奇怪编译器特性。
    • @KerrekSB:我没有意识到它已被弃用/hacky,感谢您的提示。
    【解决方案2】:

    添加#include &lt;cctype&gt;(如果您不是abusing namespace std;,则添加std::isspace等)。

    始终包含您需要的所有标题,不要依赖隐藏的嵌套包含。

    您可能还必须消除&lt;locale&gt; 中的重载与另一个重载的歧义。通过添加显式演员来做到这一点:

    word.erase(std::remove_if(word.begin(), word.end(),
                              static_cast<int(&)(int)>(std::isspace)),
               word.end());
    

    【讨论】:

      【解决方案3】:

      如果我执行以下任一操作,它将使用 g++ 进行编译:

      • 删除using namespace std;并将string更改为std::string;或
      • isspace 更改为::isspace(等等)。

      其中任何一个都会导致 isspace(等)从主命名空间中获取,而不是被解释为可能意味着 std::isspace(等)。

      【讨论】:

        【解决方案4】:

        问题在于 std::isspace(int) 将 int 作为参数,但字符串由 char 组成。所以你必须编写自己的函数:

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

        这同样适用于其他两个函数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-08-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-14
          相关资源
          最近更新 更多