今天运行如下代码时:
#include <algorithm>
#include <cctype>
using namespace std;
int main()
{
/other code/
istream_iterator<string> in_iter(fin), eof;
while(in_iter != eof)
{
string s = in_iter++;
string word;
remove_copy_if(s.begin(), s.end(),
back_inserter(word), ispunct);
}
/other code*/
}
在mingw492_32下编译提示如下错误:
error: no matching function for call to remove_copy_if(std::basic_string<char>::iterator, std::basic_string<char>::iterator, std::back_insert_iterator<std::basic_string<char> >, <unresolved overloaded function type>)’ std::back_inserter(word), ispunct);
提示ispunct是无法解析的重载函数,按照平时使用的经验,ispunct是cctype库中定义的一个用来判断一个字符是否为标点符号的函数,这儿怎么回提示重载呢?后来在SO(Stackoverflow)上找到了答案。
由于C++在标准库STL中也定义了ispunct函数,定义于std命名空间,且是一个模板函数。由于程序直接通过using namespace std导入了std命名空间,程序默认使用STL库中的ispunct,导致编译器直接使用了未特化的模板函数,并未使用cctype库中的此函数,因此编译无法通过。
正如SO上所说的,为了避免此类问题出现,我们应该尽量避免直接使用using namespace std;,由于std命名空间定义了很多标识符,直接导入全部的std命名空间会产生意想不到的冲突。在将程序修改后,编译通过。
#include <algorithm>
#include <cctype>
using std::string;
int main()
{
/*other code*/
std::istream_iterator<std::string> in_iter(fin), eof;
while(in_iter != eof)
{
string s = *in_iter++;
string word;
std::remove_copy_if(s.begin(), s.end(),
std::back_inserter(word), ispunct);
}
/*other code*/
}