이 질문은 일반적으로 C++과 관련하여보다 적절하게 질문 할 수 있지만, 리눅스에서 gcc를 사용하고 있기 때문에 그 맥락입니다. 다음의 프로그램을 고려 : 프로그램을 실행하면C++ : 연산자 []에 액세스 할 때 const 대신 const가 아닌 gcc를 사용하는 이유는 무엇입니까?
#include <iostream>
#include <map>
#include <string>
using namespace std;
template <typename TKey, typename TValue>
class Dictionary{
public:
map<TKey, TValue> internal;
TValue & operator[](TKey const & key)
{
cout << "operator[] with key " << key << " called " << endl;
return internal[key];
}
TValue const & operator[](TKey const & key) const
{
cout << "operator[] const with key " << key << " called " << endl;
return internal.at(key);
}
};
int main(int argc, char* argv[])
{
Dictionary<string, string> dict;
dict["1"] = "one";
cout << "first one: " << dict["1"] << endl;
return 0;
}
을, 출력은 : 내가 좋아하는 것이 무엇
operator[] with key 1 called
operator[] with key 1 called
first one: one
컴파일러가 두 번째 호출에 대신 operator[]const
방법을 선택하는 것입니다. 그 이유는 이전에 dict [ "1"]을 사용하지 않고 operator[]
을 호출하면 존재하지 않는 데이터를 내부 맵으로 생성하기 때문에 원하는 것은 디버깅 출력을하는 것이었기 때문입니다. 치명적인 응용 프로그램 오류.
나는 GET과 세트 작업과 장소 게터가 존재하지 않는 무언가에 액세스하려고하는 경우는 예외를 던질 수있는 C#을 인덱스 연산자 같은 것입니다 찾고 있어요 동작 :
class MyDictionary<TKey, TVal>
{
private Dictionary<TKey, TVal> dict = new Dictionary<TKey, TVal>();
public TVal this[TKey idx]
{
get
{
if(!dict.ContainsKey(idx))
throw KeyNotFoundException("...");
return dict[idx];
}
set
{
dict[idx] = value;
}
}
}
을
그래서 const가 아닌 액세스가 필요하지 않을 때 gcc가 const 호출을 통해 non-const 호출을 선호하는지 궁금합니다.
사용할 수있는 버전이 const이고 "폐기 규정 자"오류가 발생하지 않는 한 비 const를 호출합니다. 분명히 컴파일러는 어떤 버전이 존재하는지 알기 때문에 내 데이터를 파괴하지 않는 버전을 사용할 수 있습니다. 필자는 개인적으로 이것이 나쁜 컴파일러 동작이라고 생각하므로 저를 계몽하십시오. 다른 방법으로 비 const를 선호하는 것이 더 안전한 AFAICT 일 때 왜이 방법으로이 작업을 수행 했습니까? – JonasW
은 더 안전 해 보일지 모르지만 너무 논리적이지는 않습니다. * 최고 * 일치는 정확히 동일한 유형 및 constness이므로 비 const 하나입니다. 그 후에 다른 성냥을 찾을 수 있습니다. 일반적으로이 결과는 놀랄 일이 아닙니다. 안전을 원하는 경우, 그것을 사용하도록 지시해야합니다. –