6

谁能告诉我这个程序的错误是什么

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    string str = "Now";

    transform(str.begin(), str.end(), str.begin(), toupper);

    cout<<str;

    return 0;
}

错误:

"no matching function for call to 'transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unresolved overloaded function type>)'
compilation terminated due to -Wfatal-errors."
4

3 回答 3

11

name 有两个函数toupper。一个来自cctype标题:

int toupper( int ch );

第二个来自locale标题:

charT toupper( charT ch, const locale& loc );

编译器无法推断应该使用哪个函数,因为您允许命名空间std。您应该使用范围解析运算符( ::) 来选择在全局空间中定义的函数:

transform(str.begin(), str.end(), str.begin(), ::toupper);

或者,更好的是:不要使用using namespace std.


感谢@Praetorian -

这可能是错误的原因,但添加::可能并不总是有效。如果包含cctype toupper则不保证存在于全局命名空间中。演员表可以提供必要的消歧 static_cast<int(*)(int)>(std::toupper)

因此,调用应如下所示:

std::transform
(
    str.begin(), str.end(),
    str.begin(),
    static_cast<int(*)(int)>(std::toupper)
);
于 2013-05-28T12:49:41.357 回答
3

为了使用toupper,您需要包含头文件:

#include <cctype>

您还需要包含头文件:

#include <string>

问题是std::toupper作为int参数,whilestd::transform将传递char给函数,因此,它有一个问题(由@juanchopanza 提供)。

您可以尝试使用:

 #include <functional>
 std::transform(s.begin(), s.end(), s.begin(), std::ptr_fun<int, int>(std::toupper));

请参阅std::transform中的示例代码

或者您可以实现自己toupperchar作为参数。

于 2013-05-28T12:52:11.980 回答
0

由于编译器隐藏在其错误消息中,真正的问题是 toupper 是一个重载函数,编译器无法确定您想要哪个。有 C toupper(int) 函数,它可能是也可能不是宏(可能不在 C++ 中,但 C 库关心吗?),还有 std::toupper(char, locale) 来自(毫无疑问) ,您通过using namespace std;.

Tony 的解决方案有效,因为他不小心用他的单独函数解决了重载问题。

于 2013-05-28T12:56:45.193 回答