개발/C++

C ++ 맵 액세스가 한정자를 버림 (const)

MinorMan 2020. 9. 24. 00:36
반응형

<질문>

다음 코드는지도를 const로 operator [] 메서드에 전달하면 한정자가 삭제된다고 말합니다.

#include 
#include 
#include 

using namespace std;

class MapWrapper {
public:
    const int &get_value(const int &key) const {
        return _map[key];
    }

private:
    map _map;
};

int main() {
    MapWrapper mw;
    cout << mw.get_value(42) << endl;
    return 0;
}

맵 액세스에서 발생 가능한 할당 때문입니까? 맵 액세스가있는 함수를 const로 선언 할 수 없습니까?

MapWrapper.cpp : 10 : 오류 : 'const std :: map 전달 , std :: allocator >> '를'_Tp & std :: map <_Key, _Tp, _Compare, _Alloc> :: operator [] (const _Key &) [with _Key = int, _Tp = int, _Compare = std :: less , _Alloc = std :: allocator >] '는 한정자를 버립니다.


<답변1>

std :: map의 연산자 []는 const로 선언되지 않았으며 동작 때문일 수 없습니다.

T & operator [] (const Key & key) 키에 해당하는 키에 매핑 된 값에 대한 참조를 반환하여 해당 키가 아직없는 경우 삽입을 수행합니다.

결과적으로 함수를 const로 선언 할 수 없으며지도의 operator []를 사용합니다.

std :: map의 find () 함수를 사용하면 맵을 수정하지 않고도 키를 조회 할 수 있습니다.

find ()는 키 (.first)와 값 (.second)을 모두 포함하는 std :: pair에 대한 반복자 또는 const_iterator를 반환합니다.

C ++ 11에서는 std :: map에 at ()을 사용할 수도 있습니다. 요소가 존재하지 않으면 [] 연산자와 달리 함수는 std :: out_of_range 예외를 발생시킵니다.


<답변2>

operator []에는 const 한정된 오버로드가 없기 때문에 const 한정 함수에서 안전하게 사용할 수 없습니다. 이는 현재 과부하가 키 값을 반환하고 설정하는 목표로 구축 되었기 때문일 수 있습니다.

대신 다음을 사용할 수 있습니다.

VALUE = map.find(KEY)->second;

또는 C ++ 11에서는 at () 연산자를 사용할 수 있습니다.

VALUE = map.at(KEY);

<답변3>

해당 메서드는 const가 아니므로 맵을 수정할 수 있으므로 const 인 맵에는 operator []를 사용할 수 없습니다 (_map [key]에 할당 할 수 있음). 대신 find 메소드를 사용해보십시오.


<답변4>

일부 최신 버전의 GCC 헤더 (내 컴퓨터의 4.1 및 4.2)에는 const로 선언 된 비표준 멤버 함수 map :: at ()이 있으며 키가 맵에 없으면 std :: out_of_range를 던집니다.

const mapped_type& at(const key_type& __k) const

함수 주석의 참조에서 이것이 표준 라이브러리의 새 멤버 함수로 제안 된 것으로 보입니다.


<답변5>

첫째, _로 시작하는 기호는 언어 구현 / 컴파일러 작성기에 예약되어 있으므로 사용해서는 안됩니다. _map이 다른 사람의 컴파일러에서 구문 오류가되는 것은 매우 쉬울 것이며, 당신은 자신을 비난 할 사람이 없을 것입니다.

밑줄을 사용하려면 시작 부분이 아니라 끝 부분에 넣으십시오. Microsoft 코드에서이 작업을 수행하는 것을 보았 기 때문에이 실수를했을 것입니다. 기억하세요, 그들은 그들 자신의 컴파일러를 작성하기 때문에 그것을 피할 수 있습니다. 그럼에도 불구하고 그것은 나쁜 생각입니다.

연산자 []는 참조를 반환 할뿐만 아니라 실제로 맵에 항목을 생성합니다. 따라서 매핑을 얻는 것이 아니라 매핑이 없으면 새로 만드는 것입니다. 그것은 당신이 의도 한 것이 아닙니다.

반응형