代码之家  ›  专栏  ›  技术社区  ›  Sambatyon

重载未编译的函数

  •  2
  • Sambatyon  · 技术社区  · 16 年前

    我是从O'ReLyLy的C++ C++烹饪书中学习的,我尝试了其中一个例子,下面是代码:

    #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版本(string),而只使用wchar\t版本,那么一切都会顺利进行。

    3 回复  |  直到 16 年前
        1
  •  1
  •   Johannes Schaub - litb    16 年前

    isspace 也是C++中的模板,它接受模板字符和使用它的区域。 std::ctype<T>

    请尝试指定您指的是C兼容版本: static_cast<int(*)(int)>(isspace) clang PR . 请参阅Faisal的第一组测试用例中的第二个案例,以了解类似的案例。


    有人在IRC上指出这个代码会调用 使用 char -但是 空间 拿 int unsigned char EOF . 现在万一 在您的PC上签名并存储负的非EOF值,这将导致未定义的行为。

    std::isspace

        2
  •  1
  •   Fozi    16 年前

    尝试 rtrimws(ws, ::isspace); .

    另外,请注意,您应该使用反向迭代器。

        3
  •  0
  •   Kirill V. Lyadvinsky    16 年前

    那是因为 isspace 是c++中的模板函数。它无法推断 F . 如果你想用C语言 空间 您可以完全限定其名称,如下所示:

    void rtrimws(string& ws){
        rtrimws(ws, ::isspace); // this will use isspace from global namespace
                                // C++ version belongs to the namespace `std`
    }
    

    这是一个很好的例子,为什么你不应该使用 using namespace std