【问题标题】:no matching function for call to 'transform [duplicate]调用“转换”没有匹配的功能[重复]
【发布时间】:2013-05-28 12:46:14
【问题描述】:

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

#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."

【问题讨论】:

  • 试试..., ::toupper);
  • 尝试#include &lt;locale&gt; 然后std::ctype::toupper 作为参数。
  • 当您处理无法弄清楚的错误时,不使用-Wfatal-errors 进行编译可能会有所帮助,因为该开关会抑制相关信息。

标签: c++


【解决方案1】:

有两个函数名为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 -

这可能是错误的原因,但添加:: 可能并不总是 工作。如果包含cctypetoupper不保证存在于 全局命名空间。演员表可以提供必要的消歧 static_cast&lt;int(*)(int)&gt;(std::toupper)

所以,调用应该是这样的:

std::transform
(
    str.begin(), str.end(),
    str.begin(),
    static_cast<int(*)(int)>(std::toupper)
);

【讨论】:

  • 这可能是错误的原因,但添加:: 可能并不总是有效。如果包含 cctype,则不保证 toupper 存在于全局命名空间中。演员表可以提供必要的消歧 static_cast&lt;int(*)(int)&gt;(std::toupper)
  • @Praetorian,是的,你是对的,谢谢。
  • 是的,非常感谢
【解决方案2】:

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

#include <cctype>

你还需要包含头文件:

#include <string>

问题是std::toupperint 作为参数,而std::transform 会将char 传递给函数,因此,它有问题(由@juanchopanza 提供)。

您可以尝试使用:

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

参见std::transform 的示例代码

或者你可以实现你自己的toupper,它将char作为参数。

【讨论】:

  • 我包含了 但它没有用
  • @user2413497 尝试检查我包含的链接?它在链接底部有完整的示例和解释。
  • @juanchopanza 我同意。我现在会更新帖子。
  • @juanchopanza,你确定吗? std::transform 函数的最后一个参数是模板化的。 std::transform 不在乎,接受它intchar。来自 cppreference:The type Type must be such that an object of type InputIt can be dereferenced and then implicitly converted to Type. The type Ret must be such that an object of type OutputIt can be dereferenced and assigned a value of type Ret.
  • @很快你有一个很好的解释为什么它不能与std::toupper一起工作吗?
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-04
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 2021-11-27
    • 2019-11-08
    • 1970-01-01
    相关资源
    最近更新 更多