liu*_*liu 28 c++ compiler-errors lowercase toupper tolower
鉴于代码:
#include <iostream>
#include <cctype>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string s("ABCDEFGHIJKL");
transform(s.begin(),s.end(),s.begin(),tolower);
cout<<s<<endl;
}
Run Code Online (Sandbox Code Playgroud)
我收到错误:
呼叫没有匹配功能
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>)
什么是"未解决重载函数类型"是什么意思?
如果我用tolower我写的函数替换它,它不再是错误.
dav*_*vka 29
尝试使用::tolower.这解决了我的问题.
Dav*_*eas 22
问题很可能与多次重载有关tolower,编译器无法为您选择一个.您可以尝试对其进行限定以选择其特定版本,或者您可能需要提供一个强制歧义的函数指针.该tolower函数可以在<locale>标题中存在(多个不同的重载),也可以在<cctype>.
尝试:
int (*tl)(int) = tolower; // Select that particular overload
transform(s.begin(),s.end(),s.begin(),tl );
Run Code Online (Sandbox Code Playgroud)
这可以通过演员阵容在一行中完成,但可能更难以阅读:
transform(s.begin(),s.end(),s.begin(),(int (*)(int))tolower );
Run Code Online (Sandbox Code Playgroud)
Jon*_*Mee 20
让我们看一下从最差开始到最佳状态的选项列表.我们将在此列出它们并在下面讨论它们:
transform(cbegin(s), cend(s), begin(s), ::tolower)transform(cbegin(s), cend(s), begin(s), static_cast<int(*)(int)>(tolower))transform(cbegin(s), cend(s), begin(s), [](const unsigned char i){ return tolower(i); })您问题中的代码transform(s.begin(), s.end(), s.begin(), tolower)会产生如下错误:
呼叫没有匹配功能
transform(std::basic_string<char>::iterator, std::basic_string<char>::iterator, std::basic_string<char>::iterator, <unresolved overloaded function type>)
那你得到一个"未解决重载函数型"的原因是有2个tolowerS IN的std命名空间:
locale库定义template <typename T> T tolower(T, const locale&)cctype库定义int tolower(int)1是davka提供的解决方案.它通过利用一个事实,解决你的错误locale的tolower不全局命名空间中定义.
根据您的情况locale,tolower可能值得考虑.你可以在tolower这里找到s 的比较:C++中的哪个tolower?
不幸的是1取决于cctype的tolower全局命名空间被定义.让我们来看看为什么情况可能并非如此:
您正确使用#include <cctype>,因为#include <ctype.h>在C++中已弃用:http://en.cppreference.com/w/cpp/header
但是C++标准在D.3 [depr.c.headers]中声明了头文件中的声明:
未指定是否首先在命名空间的命名空间范围(3.3.6)中声明或定义这些名称
std,然后通过显式使用声明将其注入全局命名空间范围(7.3.3)
因此,我们可以保证我们的代码独立于实现的唯一方法是使用tolowerfrom namespace std.2是DavidRodríguez提供的解决方案 - dribeas.它利用了以下事实static_cast:
用于通过执行到特定类型的函数到指针转换来消除函数重载的歧义
在我们继续之前,让我评论一下,如果您发现int (*)(int)有点混乱,可以在这里阅读更多有关函数指针语法的内容.
可悲的是,输入参数存在另一个问题tolower,如果是:
不能表示为unsigned char且不等于EOF,行为未定义
您使用的string是使用以下类型的元素:char.标准状态char具体为7.1.6.2 [dcl.type.simple] 3:
实现定义了
char类型对象是表示为有符号数还是无符号数.该signed说明符的力量char要签名的对象
因此,如果实现将a定义char为意味着a,signed char则1和2都将导致对应于负数的所有字符的未定义行为.(如果使用ASCII字符编码,则与负数对应的字符为扩展ASCII.)
通过将输入转换为unsigned char传递给它之前的输入,可以避免未定义的行为tolower.3实现了使用接受unsigned charby值的lambda ,然后将其传递给tolower隐式转换为int.
为了保证所有兼容实现的定义行为,独立于字符编码,您需要使用transform(cbegin(s), cend(s), begin(s), [](const unsigned char i){ return tolower(i); })或类似的东西.
大卫已经确定了这个问题,即:
<cctype>的 int tolower(int c)<locale>的 template <typename charT> charT tolower(charT c, locale const& loc)使用第一个更容易,但是一旦你处理了签名字符中的低-ascii(0-127)之外的任何其他内容,就会出现未定义的行为(不幸).顺便说一下,我建议定义char为unsigned.
模板版本会很好,但你必须使用它bind来提供第二个参数,它必然是丑陋的......
那么,我可以介绍一下Boost String Algorith m库吗?
更重要的是:boost::to_lower:)
boost::to_lower(s);
Run Code Online (Sandbox Code Playgroud)
表现力是可取的.