我正在关注 O'Reilly 的 C++ Cookbook 一书,我尝试了其中一个示例,这是代码:
#include <string>
#include <iostream>
#include <cctype>
#include <cwctype>
using namespace std;
template<typename T, typename F>
void rtrimws(basic_string<T>& s, F f){
if(s.empty())
return;
typename basic_string<T>::iterator p;
for(p = s.end(); p != s.begin() && f(*--p););
if(!f(*p))
p++;
s.erase(p, s.end());
}
void rtrimws(string& ws){
rtrimws(ws, isspace);
}
void rtrimws(wstring& ws){
rtrimws(ws, iswspace);
}
int main(){
string s = "zing ";
wstring ws = L"zonh ";
rtrimws(s);
rtrimws(ws);
cout << s << "|\n";
wcout << ws << "|\n";
}
当我尝试编译它时,出现以下错误
trim.cpp: In function ‘void rtrimws(std::string&)’:
trim.cpp:22: error: too many arguments to function ‘void rtrimws(std::string&)’
trim.cpp:23: error: at this point in file
我不明白哪里出了问题。如果我不使用 char 版本(字符串)而只使用 wchar_t 版本,一切都会顺利进行。
顺便说一下,我在 64 位 ubuntu 机器上使用 g++ 4.4.3
最佳答案
isspace
也是 C++ 中的一个模板,它接受一个模板化字符以及一个使用方面 std::ctype<T>
的语言环境。对给定的字符进行分类(因此它无法决定采用哪个版本,因此会忽略模板)。
尝试指定您指的是 C 兼容版本:static_cast<int(*)(int)>(isspace)
.编译器之间的差异可能来自编译器之间对重载函数名称的推导处理不一致 - 参见 clang PR .请参阅 Faisal 的第一组测试用例中的第二个案例以了解类似案例。
有人在 IRC 上指出这段代码会调用 isspace
使用 char
- 但是isspace
需要 int
并要求给定的值在 unsigned char
的范围内值或 EOF
.现在以防char
在您的 PC 上签名并存储负的非 EOF 值,这将产生未定义的行为。
我建议像@Kirill 在评论中所说的那样做,只使用模板化的 std::isspace
- 然后你也可以摆脱函数对象参数。
关于c++ - 重载函数不编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3679801/