c++ - 重载函数不编译

标签 c++ templates stl

我正在关注 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/

相关文章:

c++ - 最大数 < x?

c++ - 如何在类中使用重载的 const_iterator?

javascript - Spidermonkey:实现 "this"?

c++ - 为什么优先级队列需要底层容器的front()、pop_back()而不是back()、pop_back()?

django - 如何在收到信号时使 django 模板缓存 key 过期?

c++ - "::"中的 "::tolower"是什么意思?

c++ - 在 vector 图上使用 initializer_list

c++ - 从 C/C++ 中的函数返回不带静态整数的数组指针

c++ - 遍历多个集合的数据结构

c++ - 我可以访问一般传递到模板中的结构吗?