vs2005 키워드 for each를 std::map에 사용시 애매한 결과가 생?

프로그래밍 일반에 관한 포럼입니다.

Moderator: 류광

Locked
꽃집총각
Posts: 55
Joined: 2003-03-29 10:26
Location: K사.
Contact:

vs2005 키워드 for each를 std::map에 사용시 애매한 결과가 생?

Post by 꽃집총각 »

Code: Select all

#include <iostream>
#include <map>

struct TestData
{
	int nA;
	std::string strB;
	int nC;
};

void main()
{
	TestData data;
	data.nA = 10;
	data.strB = "가나다1";
	data.nC = 20;

	std::map<int,TestData〉 mapData;
	mapData[10] = data;
	mapData[20] = data;
	mapData[30] = data;
	mapData[40] = data;
	mapData[10].strB = "가나다1";
	mapData[20].strB = "가나다2";
	mapData[30].strB = "가나다3";
	mapData[40].strB = "가나다4";

	for each( const std::pair<int,TestData〉 pr in mapData )	// ok
	{
		std::cout << pr.second.nA << " "
			<< pr.second.strB.c_str() << " "
			<< pr.second.nC << std::endl;
	}

	for each( const std::pair<int,TestData〉& pr in mapData )	// error
	{
		std::cout << pr.second.nA << " "
			<< pr.second.strB.c_str() << " "
			<< pr.second.nC << std::endl;
	}
}
보통은 컨테이너에 객체의 포인터를 많이 넣지만
간단하게 데이터만 묶어둔 구조체 같은 경우는 저렇게 직접 객체 자체를 넣기도 하는데,
  • 1. std::map 컨테이너에
    2. 포인터가 아닌 실제 객체를 넣는 경우
    3. reference 형태로 for each 루프를 돌게 되면
이상한 결과가 발생하네요.

위 코드의 결과는 아래와 같습니다.
10 가나다1 20
10 가나다2 20
10 가나다3 20
10 가나다4 20
10 20
10 20
10 20
10 20
계속하려면 아무 키나 누르십시오 . . .
TestData 구조체에 복사생성자, 소멸자를 정의해놓고 BreakPoint를 찍어보면
오작동하는 loop의 경우에도 std::pair<...>가 계속 복사되는 걸 확인할 수 있는데
왜 그렇게 되는지를 영 모르겠습니다 *~*

원인을 설명해주실 수 있는 분 계신가요.
답변 부탁드립니다.

ps. 위 소스코드에서 템플릿 닫는 괄호 ( > )가 다른걸로 인식되는지 자꾸 사라지길래 다른 기호 ( 〉 )로 바꾸어 적었습니다. 복사해서 테스트 하시려면 이부분 고쳐 주세요 ^^;
Last edited by 꽃집총각 on 2007-11-21 13:44, edited 1 time in total.
nikola2
Posts: 886
Joined: 2005-07-12 01:19
Location: (주) 신규 소프트

Re: vs2005 키워드 for each를 std::map에 사용시 애매한 결과가

Post by nikola2 »

원인은 정확히 모르겠지만...
다음과 같이 하면 일단 되는 것은 확인했습니다..

for each( std::map<int>::const_reference pr in mapData )

map의 traits로 되있는 const_reference는 정확하게
동일한 타입인 const pair & 로 작동하긴 합니다만...

내부 원리를 아시는 분이 설명주시면 좋겠네요...

---
에효..대략적인 원인은 파악이 되었네요......
맵 데이터의 실제 value_type이 pair<int,Data>가 아니고 pair<const int ,Data> 입니다....
다른 타입을 인자로 주고, 참조를 거치니 문제가 된듯 합니다....
---
Last edited by nikola2 on 2007-11-21 13:44, edited 3 times in total.
집사람이 국력이다...
비회원

Post by 비회원 »

비표준 키워드를 쓰기보단

차라리 Boost용 for each를 쓰는게 어떨지
jupi
Posts: 4
Joined: 2007-06-27 09:25
Contact:

Post by jupi »

& 사용시 vector와 set을 테스트해보니 전부 정상 작동하네요.

특이하게 map만 저런식으로 작동하네요.
꽃집총각
Posts: 55
Joined: 2003-03-29 10:26
Location: K사.
Contact:

대단하십니다 +_+)b

Post by 꽃집총각 »

nikola2 wrote:원인은 정확히 모르겠지만...

---
에효..대략적인 원인은 파악이 되었네요......
맵 데이터의 실제 value_type이 pair<int,data〉가 아니고 pair<const int,data〉 입니다....
다른 타입을 인자로 주고, 참조를 거치니 문제가 된듯 합니다....
---
그렇군요.
대단하십니다. 이문제로 한참을 삽질하고 있었는데 금방 알아내셨네요 ^^;
비표준 키워드를 쓰기보단

차라리 Boost용 for each를 쓰는게 어떨지
boost.foreach는 매크로로 정의되어 있기 때문에, map을 사용하는 경우는 쉼표를 어떻게든 처리해줘야 합니다.
http://boost.org/doc/html/foreach/pitfalls.html -> 여기에도 쉼표에 대한 이야기가 있더군요.
그래서 typedef 해주거나 변수선언을 미리 하거나 해야 하는데, 이게 좀 거시기 합니다.

오늘 저녁 자기 전에 니콜라 만세 삼창 하고 자겠습니다.
감사합니다. 꾸벅 ~
ohoneman
Posts: 11
Joined: 2004-06-09 11:25

시퀀스 컨테이너와 연관컨테이너의 차이때문이지 않을까 싶네요.

Post by ohoneman »

standard sequence container
- vector, string, deque,list

standard associate container
- map, set , multimap, multiset


연관컨테이너는 데이터 입력시 자동 정렬이 되기 때문에,

데이터 입력후 참조를 하지 말라는 식의 내용이 있었던걸로 기억합니다.

혹시 이부분이 문제가되는 것이 아닐까요?

가만 생각해 보니 정확한지는 확실치가 않네요.

이펙티브 STL인데, 혹시 한번 참고해 보세요.
Best Regards,
Stanley.Kim
비회원

Re: 시퀀스 컨테이너와 연관컨테이너의 차이때문이지 않을까 싶네요.

Post by 비회원 »

ohoneman wrote:standard sequence container
- vector, string, deque,list

standard associate container
- map, set , multimap, multiset


연관컨테이너는 데이터 입력시 자동 정렬이 되기 때문에,

데이터 입력후 참조를 하지 말라는 식의 내용이 있었던걸로 기억합니다.

혹시 이부분이 문제가되는 것이 아닐까요?

가만 생각해 보니 정확한지는 확실치가 않네요.

이펙티브 STL인데, 혹시 한번 참고해 보세요.
이펙티브 STL을 찾아봤는데.. 제가 이해하기론 반대의 내용이더군요..
연관컨테이너가 데이터의 정렬이 일어나는게 아니라 연속메모리(contiquous-memory) 컨테이너더군요...
노드 기반 컨테이너는 오히려 참조에 있어서 안전하답니다. 연관컨테이너는 모두 노드기반이라 기술되어 있고요...

연속메모리(contiquous-memory) 컨테이너 : vector, string, deque, 비표준 rope
노드기반(node-base) 컨테이너 : list, slist, 표준 연관 컨테이너 모두, 비표준 해쉬 컨테이너

좀 오래된 글이긴 한데 누군가 참고하게 된다면 오해가 없으시라고 글 올려 봅니다.
-----------------------------------------------------------------------------------------------------------------------
대로링...
Locked