破解STL实施? [英] Broken STL implementation?

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

问题描述

编译并运行

后续程序时,我的实现是否正确无法打印空行?


#include< iostream>

#include< map>


int main()

{

std :: map< const char *,std :: string> m;

m [" foo"] =" bar";

std :: cout<< m [" foo"]<< std :: endl;

返回0;

}


g ++打印" bar",这当然是行为我想要。如果这是我的实施问题,那么我可以做什么(如果有的话)

来解决它?


-

Christopher Benson-Manica |我*应该*知道我在说什么 - 如果我

ataru(at)cyberspace.org |不,我需要知道。火焰欢迎。

解决方案

Christopher Benson-Manica写道:

我的实现是否正确只打印一个空白行
下面的程序是编译运行的吗?
#include< iostream>
#include< map>

int main()
{
std :: map< const char *,std :: string> m;
m [" foo"] =" bar";
std :: cout<< m [" foo"]<< std :: endl;
返回0;
}
g ++打印" bar",这当然是我想要的行为。如果这是我的实施的一个(另外)问题,我可以做什么,或者可以解决它?




那里不能保证第一个foo和第二个foo

相同的常量字符串。因此,这两种实现方式都是正确的。


解决方法是确保两次都传递相同的指针值




int main()

{

..

const char * pfoo =" foo" ;

m [pfoo] =" bar";

std :: cout<< m [pfoo]<< std :: endl;

}


Victor


2004年8月18日星期三16: 09:02 +0000(UTC),Christopher Benson-Manica

< at *** @ nospam.cyberspace.org>写道:

当编译并运行
以下程序时,我的实现是否正确只打印一个空行?

#include< iostream> ;
#include< map>

int main()
{
std :: map< const char *,std :: string>米;


好​​的,所以你的地图已经存在缺陷 - 你不能<比较指针值

,除非这些指针指向同一个对象(或数组)。

m [" foo"] =" bar";
std: :cout<< m [" foo"]<<的std :: ENDL;


第二个foo可能会或可能不会与第一个地址具有相同的地址

- 它是未指定的。所以可能有也可能没有未定义的行为

(这就是你所看到的)。

返回0;
}

g ++ print" bar",这当然是我想要的行为。如果这是我实施的一个(另外)问题,我可以做什么,或者可以解决它?




我你认为你的方式是根据

的内容对字符串进行排序,而不是指针值吗?如果是这样,那么你需要一些东西

喜欢:


#include< cstring>


struct strcmper

{

typedef bool result_type;

typedef const char * first_argument_type;

typedef const char * second_argument_type;

bool operator()(const char * lhs,const char * rhs)const

{

返回std :: strcmp(lhs,rhs)< ; 0;

}

};


// ...

std :: map< ; const char *,std :: string,strcmper> m;


Tom


Christopher Benson-Manica写道:

是我的当编译并运行以下程序时,实现是否正确打印空行?

#include< iostream>
#include< map>

int main()
{
std :: map< const char *,std :: string> m;
m [" foo"] =" bar";
std :: cout<< m [" foo"]<< std :: endl;
返回0;
}
g ++打印" bar",这当然是我想要的行为。如果这是我的实施的一个(另外)问题,我可以做什么工作来解决它?


这不是问题与你的图书馆。下面的代码将产生一个带有g ++的

空行,我冒昧地说,在任何标准complient

编译器上:


#include< iostream>

#include< map>


int main()

{

char foo1 [4] =" foo";

char foo2 [4] =" foo";

std :: map< const char *,std :: string,std :: less< const char *> m;

m [foo1] =" bar";

std :: cout<< m [foo2]<< std :: endl;

返回0;

}


返回您的代码:

的std ::地图< const char *,std :: string> m;




这是一个基本的想法:地图操作将调用operator<这应该是一个弱的总排序。

。该标准并不要求这包含

用于比较const char *。因此


std :: map< const char *,std :: string,std :: less< const char *> m;


更好。但是,它显然不是你想要的。


你的地图只是存储一个指向char的指针,而不是那个字符串的
副本。此外,您不要将条目的

值作为字符串进行比较,而只是按地址进行比较。由于foo1和foo2指向不同的内存位置,因此第二个程序打印一个空白行。那个

g ++打印" bar"对于你的代码表明g ++折叠了两次出现

的foo在你的代码中相同的内存位置:这告诉我们一点关于g ++处理字符串常量的
位。


建议:使用std修复你的代码: :地图中键的字符串,



最佳


Kai-Uwe


Is my implementation correct to print only a blank line when the
following program is compiled and run?

#include <iostream>
#include <map>

int main()
{
std::map< const char *, std::string > m;
m["foo"]="bar";
std::cout << m["foo"] << std::endl;
return 0;
}

g++ prints "bar", which is of course the behavior I want. If this is
a(nother) problem with my implementation, what, if anything, can I do
to work around it?

--
Christopher Benson-Manica | I *should* know what I''m talking about - if I
ataru(at)cyberspace.org | don''t, I need to know. Flames welcome.

解决方案

Christopher Benson-Manica wrote:

Is my implementation correct to print only a blank line when the
following program is compiled and run?

#include <iostream>
#include <map>

int main()
{
std::map< const char *, std::string > m;
m["foo"]="bar";
std::cout << m["foo"] << std::endl;
return 0;
}

g++ prints "bar", which is of course the behavior I want. If this is
a(nother) problem with my implementation, what, if anything, can I do
to work around it?



There is no guarantee that the first "foo" and the second "foo" are
the same constant string. Both implementations are, therefore, correct.

The work-around is to ensure that you''re passing the same pointer value
both times:

int main()
{
..
const char *pfoo = "foo";
m[pfoo] = "bar";
std::cout << m[pfoo] << std::endl;
}

Victor


On Wed, 18 Aug 2004 16:09:02 +0000 (UTC), Christopher Benson-Manica
<at***@nospam.cyberspace.org> wrote:

Is my implementation correct to print only a blank line when the
following program is compiled and run?

#include <iostream>
#include <map>

int main()
{
std::map< const char *, std::string > m;
Ok, so your map is flawed already - you can''t < compare pointer values
unless those pointers point into the same object (or array).
m["foo"]="bar";
std::cout << m["foo"] << std::endl;
The second "foo" may or may not have the same address as the first one
- it''s unspecified. So that may or may not have undefined behaviour
(which is what you''re seeing).
return 0;
}

g++ prints "bar", which is of course the behavior I want. If this is
a(nother) problem with my implementation, what, if anything, can I do
to work around it?



I think you way to have the map sorted according to the contents of
the string, not the pointer value? If so, then you need something
like:

#include <cstring>

struct strcmper
{
typedef bool result_type;
typedef const char* first_argument_type;
typedef const char* second_argument_type;
bool operator()(const char* lhs, const char* rhs) const
{
return std::strcmp(lhs, rhs) < 0;
}
};

//...
std::map< const char *, std::string, strcmper > m;

Tom


Christopher Benson-Manica wrote:

Is my implementation correct to print only a blank line when the
following program is compiled and run?

#include <iostream>
#include <map>

int main()
{
std::map< const char *, std::string > m;
m["foo"]="bar";
std::cout << m["foo"] << std::endl;
return 0;
}

g++ prints "bar", which is of course the behavior I want. If this is
a(nother) problem with my implementation, what, if anything, can I do
to work around it?

This is not a problem with your library. The following code will yield a
blank line with g++, and I venture to say, on any standard complient
compiler:

#include <iostream>
#include <map>

int main()
{
char foo1 [4] = "foo";
char foo2 [4] = "foo";
std::map< const char *, std::string, std::less< const char * > m;
m[foo1]="bar";
std::cout << m[foo2] << std::endl;
return 0;
}

Back to your code:
std::map< const char *, std::string > m;



This is a bas idea: map operations will call operator< which is supposed to
be a weak total ordering. The standard makes no requirement that this holds
for comparision of const char *. Thus

std::map< const char *, std::string, std::less< const char * > m;

is better. However, it is clearly not what you want.

What happens is that your map m just stores a pointer to char and not a
copy of that string. Moreover, you donot compare the entries by their
values as strings but just by their address. Since foo1 and foo2 point to
different memory locations, the second programm prints a blank line. That
g++ prints "bar" for your code indicates that g++ folded the two occurences
of "foo" in your code to the same memory location: this tells us a little
bit about g++ handles string constants.

Recommendation: fix your code by using std::string for the keys in the map,
as well.
Best

Kai-Uwe


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

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