最近编写了一小段程序,在GNU编译器下能编译通过,但在VC编译器下却显示一大堆错误。查看编译信息,其中错误提示如下:
error C2679: binary '>>' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' (or there is no acceptable conversion)
fatal error C1903: unable to recover from previous error(s); stopping compilation
这段程序如下所示,程序不断从stdin中读入单词,若该单词是第一次出现,则输出该单词,否则忽略。注:输入中单词以空格间隔,标点符号仅出现在单词后面,且和单词字母间没有其他字符。
例如输入:where there is a will, there is a way.
则应输出:where there is a will way
#include <iostream> #include <cstring> #include <set> using namespace std; int main() { char str[100]; string word; set<string> words; while(cin >> str){ int n = strlen(str) - 1; char c = str[n]; if (!isalpha(c)) str[n] = 0; word = str; if (words.find(word) == words.end()){ cout << word << " "; words.insert(word); } } return 0; }
通过定位错误,是其中cout << word << " "一行代码有误。经过一番尝试之后,将该行代码修改为 cout << word.c_str() << " "; 完整代码如下:
#include <iostream> #include <cstring> #include <set> using namespace std; int main() { char str[100]; string word; set<string> words; while(cin >> str){ int n = strlen(str) - 1; char c = str[n]; if (!isalpha(c)) str[n] = 0; word = str; if (words.find(word) == words.end()){ cout << word.c_str() << " "; words.insert(word); } } return 0; }
但此次错误信息却更多了,且大多是C2784错误:
error C2784: 'bool __cdecl std::operator ==(const class std::multiset<_K,_Pr,_A> &,const class std::multiset<_K,_Pr,_A> &)' : could not deduce template argument for 'const class std::multiset<_K,_Pr,_A> &' from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >'而且这次定位错误,却定位了到了set模板文件。无奈之下只好继续修改代码,将set修改为vector。修改后代码如下:
#include <iostream> #include <cstring> #include <vector> using namespace std; bool my_find(vector<string> &words, string &str) { for(vector<string>::iterator iter = words.begin(); iter != words.end(); ++iter) if((*iter) == str) return true; return false; } int main() { char str[100]; string word; vector<string> words; while(cin >> str){ int n = strlen(str) - 1; char c = str[n]; if (!isalpha(c)) str[n] = 0; word = str; if (!my_find(words, word)){ cout << word.c_str() << " "; words.push_back(word); } } return 0; }但是到了这一步,编译器依然还是报C2784错误。但这个程序已经将编译错误定位到了if((*iter) == str)这一行。于是,我做了最后的修改。代码如下:
#include <iostream> #include <cstring> #include <vector> using namespace std; bool my_find(vector<string> &words, string &str) { for(vector<string>::iterator iter = words.begin(); iter != words.end(); ++iter) //if((*iter) == str) if(strcmp((*iter).c_str(), str.c_str()) == 0) return true; return false; } int main() { char str[100]; string word; vector<string> words; while(cin >> str){ int n = strlen(str) - 1; char c = str[n]; if (!isalpha(c)) str[n] = 0; word = str; if (!my_find(words, word)){ cout << word.c_str() << " "; words.push_back(word); } } return 0; }
到了这一步,代码终于编译通过。我也终于松了口气,但心头还是满是疑惑,为什么这些代码在GNU的编译器下可以正常编译,在VC的编译器下就是不行呢?突然我灵光一闪!为何不上网搜一搜,看看别人是怎么解决的呢?于是我搜索了错误提示信息。如下一个帖子中的回复说明了这个问题:
http://bbs.csdn.net/topics/40256358
其中三楼和五楼回答了这一问题。
至此,问题告一段路。回到我的第一个解决方案,在添加完整的头文件后,终于在GNU和VC的编译器下都顺利通过了。