日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Why “transform(s.begin(),s.end(),s.begin(),tolower)” can't be complied successfully?

發布時間:2024/3/24 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Why “transform(s.begin(),s.end(),s.begin(),tolower)” can't be complied successfully? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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?

up vote 7 down vote favorite 3 #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.

c++
share|improve this question edited Apr 4 '11 at 13:39 Ken Bloom
27.4k254115
asked Apr 4 '11 at 13:33 liu
312213
?
2?
The return type of main is int, 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
add a comment

4 Answers

active oldest votes
up vote 8 down vote accepted

try using ::tolower. This fixed the problem for me

share|improve this answer answered Apr 4 '11 at 13:48 davka
3,96122152
?
1?
It's right. What's difference between tolower and ::tolower? –? liu Apr 4 '11 at 14:06
?
@liu: it's as @David wrote - the "::" selects the tolower from the global namespace –? davka Apr 4 '11 at 14:16
add a comment
up vote 13 down vote

The 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 overload transform(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 );
share|improve this answer answered Apr 4 '11 at 13:38 David Rodríguez - dribeas
124k5117292
?
3?
But don't forget that using this version of tolower on a string like the above is undefined behavior if any of the char values are negative (which they can be on most modern systems, e.g. if any accented characters are present). –? James Kanze Apr 4 '11 at 13:49
1?
@James Kanze: good point, I decided for that overload from reading the original post (where cctype is explicitly included, while locale is not). Also, the functions in locale take more than a single argument, and that means that the code would add unrelated complexity with a bind or bind2nd to provide the default locale... –? David Rodríguez - dribeas Apr 4 '11 at 13:58
?
Thank you.I understand the problem. And using ::tolower can fix the problem –? liu Apr 4 '11 at 14:11
1?
@liu: Note that using ::tolower will work in different compilers, but it is not standard. Basically most compilers, when you include cctype the compiler is required to provide int std::tolower(int), but it is not required to add int ::tolower(int), different compilers will 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
1?
@liu Using ::tolower doesn't fix the problem. Calling ::tolower with a char argument is undefined behavior. You need to wrap it in a functional object which converts the char 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:40
show 8 more comments
up vote 2 down vote

Browsing 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 the std (from <cctype>) and root (from <ctype.h>) namespaces. I'm not sure what the #pragma does.

share|improve this answer answered Apr 4 '11 at 13:49 Mike DeSimone
20.3k23361
?
1?
the pragma signals to gcc that this file is a system header. This should typically affect diagnosis, since it's considered bad style for a compiler to emit warnings for headers that it was bundled with and should not be altered. –? Matthieu M. Apr 4 '11 at 19:12
add a comment
up vote 2 down vote

David already identified the issue, namely a conflict between:

  • <cctype>'s int tolower(int c)
  • <locale>'s template <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.

share|improve this answer answered Apr 4 '11 at 19:22 Matthieu M.
103k9109261
?
?
1) can you please explain what do you mean by 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:27
?
@davka: 1) the C++ Standard does not precise whether a char is signed or unsigned. You can qualify it if you want to be sure. However a number of functions (like int tolower(int)) have undefined behavior if invoked with a negative char... 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 the std::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:37
?
thanks, I still don't get #1. I know about char being implementation-dependent. Are you suggesting typedef unsigned char char? is it legal? –? davka Apr 5 '11 at 15:43
1?
@davka: No, it's not legal. Compilers usually have switches to let you decide, for example gcc has -fsigned-char and -funsigned-char. –? Matthieu M. Apr 5 '11 at 17:00
?
that's interesting, thanks. So, if I use -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
show 5 more comments

總結

以上是生活随笔為你收集整理的Why “transform(s.begin(),s.end(),s.begin(),tolower)” can't be complied successfully?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。