Why “transform(s.begin(),s.end(),s.begin(),tolower)” can't be complied successfully?
来源:互联网 发布:交通组织优化有哪些 编辑:程序博客网 时间:2024/06/07 13:00
From: http://stackoverflow.com/questions/5539249/why-transforms-begin-s-end-s-begin-tolower-cant-be-complied-successfu
Why “transform(s.begin(),s.end(),s.begin(),tolower)” can't be complied successfully?
#include<iostream>#include<cctype>#include<string>#include<algorithm>using namespace std;main(){ string s("ABCDEFGHIJKL"); transform(s.begin(),s.end(),s.begin(),tolower); cout<<s<<endl;}
the error:
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>)'`
What the "unresolved overloaded function type" means?
if I replace the tolower of a function written by myself ,it can work.
4 Answers
try using ::tolower
. This fixed the problem for me
tolower
from the global namespace – davka Apr 4 '11 at 14:16The problem most probably relates with multiple overloads of tolower
and the compiler is unable to select one for you. You can try qualifying it to select an specific version of it, or you might need to provide a function pointer cast to disambiguate. The tolower
function can be present (multiple different overloads) in the<locale>
header, as well as in <cctype>
.
Try:
int (*tl)(int) = tolower; // Select that particular overloadtransform(s.begin(),s.end(),s.begin(),tl );
That can be done in a single line with a cast, but it is probably harder to read:
transform(s.begin(),s.end(),s.begin(),(int (*)(int))tolower );
bind
or bind2nd
to provide the default locale
... – David Rodríguez - dribeas Apr 4 '11 at 13:58::tolower
will work in different compilers, but it is not standard. Basically most compilers, when you includecctype
the compiler is required to provide int std::tolower(int)
, but it is not required to addint ::tolower(int)
, different compilerswill provide both functions with the same implementation (one of them will forward to the other) but that is not required and might change with the next compiler release (or if you change the compiler) – David Rodríguez - dribeas Apr 4 '11 at 15:20::tolower
doesn't fix the problem. Calling::tolower
with achar
argument is undefined behavior. You need to wrap it in a functional object which converts thechar
to unsigned char
. Or buy into all of the complexity that David Rodríguez mentions with regards to the versions in<locale>
. – James Kanze Apr 4 '11 at 16:40Browsing my <ctype>
header from gcc 4.2.1, I see this:
// -*- C++ -*- forwarding header.// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005// Free Software Foundation, Inc.
...
#ifndef _GLIBCXX_CCTYPE#define _GLIBCXX_CCTYPE 1#pragma GCC system_header#include <bits/c++config.h>#include <ctype.h>// Get rid of those macros defined in <ctype.h> in lieu of real functions.#undef isalnum#undef isalpha
...
#undef tolower#undef toupper_GLIBCXX_BEGIN_NAMESPACE(std) using ::isalnum; using ::isalpha;
...
using ::tolower; using ::toupper;_GLIBCXX_END_NAMESPACE#endif
So it looks like tolower
exists in both thestd
(from <cctype>
) and root (from <ctype.h>
) namespaces. I'm not sure what the#pragma
does.
David already identified the issue, namely a conflict between:
<cctype>
'sint tolower(int c)
<locale>
'stemplate <typename charT> charT tolower(charT c, locale const& loc)
Using the first is much easier, but is undefined behavior (unfortunately) as soon as you deal with anything else than lower-ascii (0-127) in signed chars.By the way, I do recommend defining char
as unsigned.
The template version would be nice, but you would have to use bind
to provide the second parameter, and it's bound to be ugly...
So, may I introduce the Boost String Algorithm library ?
And more importantly: boost::to_lower
:)
boost::to_lower(s);
Expressiveness is desirable.
I do recommend defining char as unsigned
? 2) does boost::to_lower
assumes some character set, e.g. latin-1? – davka Apr 5 '11 at 15:27char
is signed or unsigned. You can qualify it if you want to be sure. However a number of functions (likeint tolower(int)
) have undefined behavior if invoked with a negativechar
... Look it up on your compiler, there might be a switch or a sane default. 2)boost::to_lower
is based on the C++ tolower
function, and thus depends on thestd::locale
and the ctype
facet it has been imbued with. Note that these facets cannot handle multi-characters encoding anyway... – Matthieu M. Apr 5 '11 at 15:37char
being implementation-dependent. Are you suggesting typedef unsigned char char
? is it legal? – davka Apr 5 '11 at 15:43gcc
has -fsigned-char
and -funsigned-char
. – Matthieu M. Apr 5 '11 at 17:00-funsigned-char
I should use signed char
if I want -128..127, correct? Does it work well with 3rd party libraries that are not compiled with this flag? – davka Apr 5 '11 at 17:09- Why “transform(s.begin(),s.end(),s.begin(),tolower)” can't be complied successfully?
- nyoj19(排列组合next_permutation(s.begin(),s.end()))
- It's a begin!
- let's begin
- 记录:s:iterator的一些使用(status,begin和end)
- Russell's Paradox: Here's Why Maths Can't Have A Set Of Everything
- Struts2标签如何实现For循环 像JSTL's <c:forEach begin="..." end="..." ...> 中的用法
- BEGIN...END
- begin-end
- Begin ... End
- main() // Roy Lee's CSDN blogs begin here
- Customer's Can't Login
- Can't open file: '%s.MYI'
- CodeBlocks "Can't read file's timestamp"
- 040903 A WebService 's Method ,return Value can't be Object
- begin&end
- oracle begin end
- 存储过程begin/end
- Android常用的一些make命令(转载)
- 3.基于DWR推送技术Demo
- 链队列
- library not found plods
- .net命名空间及其作用
- Why “transform(s.begin(),s.end(),s.begin(),tolower)” can't be complied successfully?
- linux 下 jira-6.3.6 配置 破解 翻译 迁移数据库
- [ExtJS5学习笔记]第二十二节 Extjs5中使用beforeLabelTpl配置给标签增加必填选项星号标志
- OGG-01224 Bad file number
- android 部分韩国手机采用KSC5601编码保存联系人,MTK平台手机无法显示联系人姓名
- redhat6.4 tftp服务器配置
- IGMP 因特网组管理协议
- Windows 8.1+VS2013 配置 OpenGL
- TAR门限模型
main
isint
, and return types in C++ have to be explicit. Some compilers will allow the code as posted, but it is non-standard, and it might break with the new compiler version or in other compilers. – David Rodríguez - dribeas Apr 4 '11 at 15:21