const 키와 non const 키의 차이점은 무엇입니까?


답변:


65
  • int그리고 const int두 가지 종류가 있습니다.

  • std::map<int, float>std::map<const int, float>, 마찬가지로 다른 유형입니다.

std::map<const int, float>and 사이의 차이 std::map<int, float>는 어느 정도는 say std::map<int, float>와 사이의 차이와 유사합니다 std::map<std::string, float>. 각각에 대해 새로운지도 유형을 얻습니다.

const그렇지 않은 경우 내부 키 유형 여전히 const int다음과 같습니다.

std::map<const int, float>::key_type       => const int
std::map<int, float>::key_type             => int

그러나 맵 키는 의미 상 불변이며 키에 대한 직접 액세스를 허용하는 모든 맵 작업 (예 : 이터레이터 역 참조 value_type)은 다음을 수행 const합니다 key_type.

std::map<const int, float>::value_type => std::pair<const int, float>
std::map<int, float>::value_type       => std::pair<const int, float>

따라서 구현에서 허용하는 경우 중요한 모든 방식에서 차이 거의 보이지 않을 수 있습니다.

하지만 항상 그런 것은 아닙니다. 표준은 공식적으로 키 유형을 복사 및 이동 가능하도록 요구 하며 일부 구현에서는 맵 노드를 재사용합니다 . 이러한 구현에서 const키 를 사용하려는 시도 는 작동하지 않습니다.


1
So the difference is largely invisible to you in every way that matters.-키 (libc ++ 등)를 복사 / 이동하는 stdlib를 사용하지 않는 한,이 경우 const 버전이 중단됩니다. 관련 토론 은 목록 .cs.uiuc.edu / pipermail / cfe-dev / 2011-July / 015926.html 을 참조하십시오 .
mitchnull 2014 년

@mitchnull 네, 좋은 자리입니다. ( btw !)
궤도

@LightnessRacesinOrbit "표준은 공식적으로 키 유형을 복사 및 이동 가능하도록 요구합니다". 움직일 수 있다는 것에 대해 제가 가지고있는 C ++ 표준 사본에서 찾을 수 없습니다. 참조 또는 섹션 번호를 제공해 주시겠습니까?
beren

이것은 훌륭한 대답이며, 마침내 const지도와 관련하여 내가 가진 전체적인 문제를 명확히했습니다 . C ++ 14는 우리를 예리하게 유지하기 위해 약간의 복잡성을 추가하는 투명한 비교기 를 도입했습니다. :)
vsoftco

아, 키가 const가 될 수 없음을 확인해 주셔서 감사합니다. 내 키는 불변되고 싶어 그리고 그것은 나를 견과류 -_- 몰았다
노엘 년 Widmer

36

키는 이미 const그것을 쓸 중복하므로, const이 경우. 한 번 입력 된 요소는 key변경할 수 없습니다.


편집 :

코멘트에서 언급 한 바와 같이,이 두 줄의 차이. 예를 들어를 받아들이는 함수를 작성하면 서로 다른 유형 이므로 map<const int, int>전달할 수 없습니다 .map<int, int>

그러나 그들은 다른 유형이지만 맵의 키가 const어쨌든 동일하기 때문에 동일하게 작동 합니다.

결론적으로 .. 유일한 차이점은 두 가지 유형이라는 것입니다. 다른 것은 신경 쓰지 말아야합니다.


18
이것은 (완전히) 정확하지 않습니다. 의 인터페이스는 std::map키 유형을로 노출 const하지만 두 템플릿 인스턴스화가이 답변이 의미하는 것과 동일하다는 것을 의미하지는 않습니다. std::map<const int, float>하고 std::map<int, float>있는 다른 유형 .
jrok 2013

1
@jrok은 정확하지만이 대답은 그렇지 않습니다. 은 key_type여전히 사실이다 int전자의 경우에.
궤도의 가벼운 경주

6
@ johnmac2332 : 이것이 빠르고 완벽하고 찬성표를 던지는 교훈이되도록합시다! = 맞습니다.
밝기 경주 궤도에

1
@ johnmac2332 빠르고 빠른 답변은 높이 평가되어야합니다. 이것은 다른 웹보다 우수한 Stackoverflow 품질 중 하나입니다. OP는 주석 섹션에서 추가 쿼리를 할 수 있습니다. 그가 고맙다고 말한다면 아마도 그가 답을 얻었다는 뜻입니다.
Grijesh Chauhan 2013

2
완벽한 사람은 없습니다. 우리 모두는 실수를하고 서로에게서 배웁니다. 우리는 :) 배우고을 도와 드릴까요?
Maroun

8

차이점은 두 번째 변형은지도의 키 유형을로 설정한다는 것입니다 const int. "수정 가능성"의 관점에서 볼 때 맵은 이미 키를 const객체 로 저장하기 때문에 중복 됩니다.

그러나 이로 인해이 두 맵의 동작에서 예상치 못한 명백하지 않은 차이가 발생할 수도 있습니다. C ++에서 type 용으로 작성된 템플릿 전문화는 type T용으로 작성된 전문화와 다릅니다 const T. 즉, 위의 두 버전의지도는 키 유형에 따라 다양한 "위성"템플릿의 다른 전문화를 사용하게 될 수 있습니다. 한 가지 예는 키 비교기 술어입니다. 첫 번째는를 사용 std::less<int>하고 두 번째는 std::less<const int>. 이 차이를 활용하면 이러한 맵을 쉽게 다른 순서로 요소를 정렬 할 수 있습니다.

이와 같은 문제는 std::unordered_map. 키를 해싱 std::unordered_map<const int, int>하기 위해 std::hash<const int>특수화 를 사용하려고 시도하기 때문에 컴파일조차하지 않습니다 . 이러한 전문화는 표준 라이브러리에 존재하지 않습니다.



2

응용 프로그램의 동작은 일반적으로 동일하지만 사용할 수있는 일부 컴파일러에 차이가 있습니다. 이 페이지를 처음 방문하게 된 구체적인 예는 다음과 같습니다.

map<const key, value>gnu 툴킷을 사용하여 성공적 으로 빌드 된 맵을 명시 적으로 지정합니다 .

그러나 Studio12 Solaris x86 빌드가 충돌합니다.


map<key, value>둘 다에서 성공적으로 구축됩니다. 응용 프로그램의 동작은 변경되지 않습니다.


어떤 방식으로 "충돌"?
궤도에서 가벼운 경주

@LightnessRacesinOrbit std::map::insert여러 선언을하는 것에 대해 불평했습니다 .
blgt

예, 위에서 언급했듯이 컴파일러에 차이가 있습니다.
blgt

일반적으로 "충돌"이라고하면 프로세스의 예기치 않은 비정상적인 런타임 종료를 의미합니다. 컴파일러 충돌은 드물지만 발생하며 (특히 새로운 언어 기능에서) 발생하며 (빌드 결과가 진행됨에 따라) 본질적으로 매우 심각합니다.
궤도

그것은 충돌빌드 가 아닌 응용 프로그램을 . 용어를 잘못 사용하고 있습니까?
blgt

0

Const 키는 키가 포인터 인 경우 유용 할 수 있습니다. const 키를 사용하면 키에 액세스 할 때 뾰족한 개체를 수정할 수 없습니다. 다음을 고려하세요.

#include <map>
#include <string>

int glob = 10;

int main() {
    std::map<const int*, std::string> constKeyMap { { &glob, "foo"} };
    std::map<int*, std::string> keyMap { { &glob, "bar" } };

    for(const auto& kv : keyMap) { *(kv.first) = 20; }; // glob = 20
    for(const auto& kv : constKeyMap) { *(kv.first) = 20; }; // COMPILE ERROR

    return 0;
}

1
(가) 때 key_type이다 const int*, 포인터하지 CONST 자체를하지만 뾰족한는 intCONST입니다.
lrineau 2014-04-02

-1

const는 한 번 정의되면 변경할 수없는 상수를 나타냅니다. const가 아닌 키는 변경 될 수 있습니다 ... 또는 변경할 수 없습니다. const (한 번 정의 된 경우)에서 "변경 없음"이 보장됩니다. , 그리고 "변경"은 비 const 항목에서 발생하거나 발생하지 않을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.