与iostream冲突? [英] tolower conflict with iostream?

查看:73
本文介绍了与iostream冲突?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编译以下代码时出错:


#include< algorithm>

#include< cctype>

#include< iostream>

#include< string>


使用命名空间std;


string&

lc(string& s)

{

transform(s.begin(),s.end(),s .begin(),tolower);

返回s;

}


int

main ()

{

string name =" DAVID" ;;


cout<<名称<< " " << lc(名字)<<结束;

返回0;

}


; g ++ lc.cc

lc.cc:在函数`std :: string& lc(std :: string&)'':

lc.cc:11:错误:没有匹配函数来调用`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>>>,< unknown type>)''


如果我不包含iostream,或者我使用不同的函数

(例如,int id(int i){return i;}),我不会得到任何错误。我在做什么

出错了什么?


/ david


-

安德烈,一个简单的农民,只有一件事在他的脑海里沿着东墙悄悄地走了过来:''安德烈,蠕动......安德烈,蠕动......安德烈,蠕动。'' br />
- 未知

解决方案

文章< 3F ************** *@nomail.com>,

David Rubin< bo *********** @ nomail.com>写道:

编译以下代码时出错:

#include< algorithm>
#include< cctype>
#include< iostream>
#include< string>

使用命名空间std;

string&
lc(string& s )
转换(s.begin(),s.end(),s.begin(),tolower);
返回s;
}

int
main()
{
字符串名称=" DAVID" ;;

cout<<名称<< " " << lc(名字)<< endl;
返回0;
}

; g ++ lc.cc
lc.cc:函数`std :: string& lc(std :: string&)'':
lc.cc:11:错误:没有匹配函数来调用`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>>>,< unknown type>)''

如果我不包含iostream,或者我使用不同的函数
(例如,int id (int i){return i;}),我没有得到任何错误。我做错了什么?




是的,但你的公司很好。这个几乎每个人都至少获得了一次b $ b。


这一个有两个踢球者(如果不是更多):


1. tolower是(也)在< locale>中原型化的模板函数:


template< class charT> charT tolower(charT c,const locale& loc);


2.允许任何标准C ++标头包含任何其他标准C ++

标头作为实现细节(参考17.4.4.1/1)。


所以当你说:


transform(s.begin(),s.end (),s.begin(),tolower);


如果模板化的tolower在范围内,则编译器无法确定

out什么模板参数尝试tolower< charT>,即使

非模板化的tolower也在范围内。显然gcc'的< iostream>

带来了tolower< charT>作为实现细节的范围。因此

错误。


这是一个偷偷摸摸的,因为它可以编译并做你想做的事情

与另一个编译器。例如它在Metrowerks上工作得很好,

除非< locale>显式包含,然后你得到一个类似的错误。


你可以使用以下咒语进行便携式修正:


transform( s.begin(),s.end(),s.begin(),(int(*)(int))tolower);


即将tolower转换为你想要的特定功能指针类型。


-Howard




" David Rubin" <博*********** @ nomail.com>在留言中写道

新闻:3F *************** @ nomail.com ...

我收到错误的时候我编译以下代码:


#include< algorithm>

#include< cctype>

#include< iostream> ;

#include< string>


使用命名空间std;


string&

lc(字符串& s)

{

transform(s.begin(),s.end(),s.begin(),tolower);

返回s;

}


int

main()

{

string name =" DAVID";


cout<<名称<< " " << lc(名字)<<结束;

返回0;

}


; g ++ lc.cc

lc.cc:在函数`std :: string& lc(std :: string&)'':

lc.cc:11:错误:没有匹配函数来调用`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>>>,< unknown type>)''


如果我不包含iostream,或者我使用不同的函数

(例如,int id(int i){return i;}),我不会得到任何错误。我在做什么

出错了什么?


/ david


-

安德烈,一个简单的农民,只有一件事在他的脑海里沿着东墙悄悄地走了过来:''安德烈,蠕动......安德烈,蠕动......安德烈,蠕动。'' br />
- 未知

__________________________________________________ ___________

我修复它的方式是做

:: tolower


Howard Hinnant< hi ***** @ metrowerks.com>写道:

您可以使用以下咒语进行便携式修正:

transform(s.begin(),s.end(),s.begin(), (int(*)(int))tolower);

即将tolower转换为您要瞄准的特定函数指针类型。




请参阅,即使标准库实现者弄错了:-)这一个但是,

然而,更微妙:''std :: tolower(int)''只能用

值来调用,这可以用''无符号来表示char''和EOF。但是,对于''char''是签名实体的系统,

很多可能的''char''值,

提升为''int'',不能表示为''unsigned char''。虽然代码上面的代码可以编译,但它不会移动。对于

真正便携式解决方案,您需要一个辅助功能:


char mytolower(char c){

return std :: tolower(static_cast< unsigned char>(c));

}


这将首先将负数''char''转换为某个正值

转换为''int'时保持相同的值。将$'$''
直接提升为''int'',然后将此值转换为无符号类型

将产生一个[通常(*)的值)]大于任何可以由''unsigned char''保存的价值。


(*):如果用于的位数''int''和''unsigned char''相同,

它会起作用...

-

< mailto :二*********** @ yahoo.com> < http://www.dietmar-kuehl.de/>

Phaidros eaSE - 简易软件工程:< http://www.phaidros.com/>


I get an error when I compile the following code:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

using namespace std;

string&
lc(string& s)
{
transform(s.begin(), s.end(), s.begin(), tolower);
return s;
}

int
main()
{
string name = "DAVID";

cout << name << " " << lc(name) << endl;
return 0;
}

; g++ lc.cc
lc.cc: In function `std::string& lc(std::string&)'':
lc.cc:11: 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> > >, <unknown type>)''

If I do not include iostream, or if I use a different function
(e.g., int id(int i){return i;}), I do not get any errors. Am I doing
something wrong?

/david

--
Andre, a simple peasant, had only one thing on his mind as he crept
along the East wall: ''Andre, creep... Andre, creep... Andre, creep.''
-- unknown

解决方案

In article <3F***************@nomail.com>,
David Rubin <bo***********@nomail.com> wrote:

I get an error when I compile the following code:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

using namespace std;

string&
lc(string& s)
{
transform(s.begin(), s.end(), s.begin(), tolower);
return s;
}

int
main()
{
string name = "DAVID";

cout << name << " " << lc(name) << endl;
return 0;
}

; g++ lc.cc
lc.cc: In function `std::string& lc(std::string&)'':
lc.cc:11: 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> > >, <unknown type>)''

If I do not include iostream, or if I use a different function
(e.g., int id(int i){return i;}), I do not get any errors. Am I doing
something wrong?



Yes, but you''re in good company. This one gets almost everyone at least
once.

There are two kickers (if not more) in this one:

1. tolower is (also) a template function prototyped in <locale>:

template <class charT> charT tolower(charT c, const locale& loc);

2. Any standard C++ header is allowed to include any other standard C++
header as an implementation detail (reference 17.4.4.1/1).

So when you say:

transform(s.begin(), s.end(), s.begin(), tolower);

and if the templated tolower is in scope, then the compiler can''t figure
out what template parameters to try out for tolower<charT>, even if the
non-templated tolower is also in scope. And apparently gcc''s <iostream>
brings tolower<charT> into scope as an implementation detail. Thus the
error.

This is a sneaky one in that it may well compile and do what you want
with another compiler. For example it works just fine on Metrowerks,
unless <locale> is explicitly included, and then you get a similar error.

You can correct it, portably, with the following incantation:

transform(s.begin(), s.end(), s.begin(), (int (*)(int))tolower);

I.e. cast tolower to the specific function pointer type that you''re
aiming for.

-Howard



"David Rubin" <bo***********@nomail.com> wrote in message
news:3F***************@nomail.com...
I get an error when I compile the following code:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

using namespace std;

string&
lc(string& s)
{
transform(s.begin(), s.end(), s.begin(), tolower);
return s;
}

int
main()
{
string name = "DAVID";

cout << name << " " << lc(name) << endl;
return 0;
}

; g++ lc.cc
lc.cc: In function `std::string& lc(std::string&)'':
lc.cc:11: 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> > >, <unknown type>)''

If I do not include iostream, or if I use a different function
(e.g., int id(int i){return i;}), I do not get any errors. Am I doing
something wrong?

/david

--
Andre, a simple peasant, had only one thing on his mind as he crept
along the East wall: ''Andre, creep... Andre, creep... Andre, creep.''
-- unknown
__________________________________________________ ___________
the way I fixed it is by doing
::tolower


Howard Hinnant <hi*****@metrowerks.com> wrote:

You can correct it, portably, with the following incantation:

transform(s.begin(), s.end(), s.begin(), (int (*)(int))tolower);

I.e. cast tolower to the specific function pointer type that you''re
aiming for.



See, even standard library implementers get it wrong :-) This one is,
however, even more subtle: ''std::tolower(int)'' can only be called with
values which can be represented by an ''unsigned char'' and EOF. However,
on systems where ''char'' is a signed entity lots of possible ''char'' values,
promoted to ''int'', cannot be represented as ''unsigned char''. Although the
above code would be portably compilable, it won''t run portably. For a
truely portable solution, you would need an auxiliary function:

char mytolower(char c) {
return std::tolower(static_cast<unsigned char>(c));
}

This will convert the negative ''char'' to some positive value first which
stays the same value when converted to ''int''. Promoting a negative ''char''
directly to ''int'' and then converting this value to an unsigned type
would yield a value which is [normally (*)] bigger than any value which
can be hold by an ''unsigned char''.

(*): if the number of bits used for ''int'' and ''unsigned char'' is identical,
it would work...
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>


这篇关于与iostream冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆