C ++에서 typedef를 사용 해야하는지 여부와 시간에 대해 약간 혼란 스럽습니다. 나는 그것이 가독성과 선명도 사이의 균형 잡힌 행동이라고 생각합니다.
typedef가없는 코드 샘플은 다음과 같습니다.
int sum(std::vector<int>::const_iterator first,
std::vector<int>::const_iterator last)
{
static std::map<std::tuple<std::vector<int>::const_iterator,
std::vector<int>::const_iterator>,
int> lookup_table;
std::map<std::tuple<std::vector<int>::const_iterator,
std::vector<int>::const_iterator>, int>::iterator lookup_it =
lookup_table.find(lookup_key);
if (lookup_it != lookup_table.end())
return lookup_it->second;
...
}
꽤 못생긴 IMO. 따라서 함수 내에 typedef를 추가하여 더보기 좋게 만듭니다.
int sum(std::vector<int>::const_iterator first,
std::vector<int>::const_iterator last)
{
typedef std::tuple<std::vector<int>::const_iterator,
std::vector<int>::const_iterator> Lookup_key;
typedef std::map<Lookup_key, int> Lookup_table;
static Lookup_table lookup_table;
Lookup_table::iterator lookup_it = lookup_table.find(lookup_key);
if (lookup_it != lookup_table.end())
return lookup_it->second;
...
}
코드는 여전히 약간 어색하지만 대부분의 악몽 자료를 제거합니다. 그러나 여전히 int 벡터 반복자가 있지만이 변형은 다음을 제거합니다.
typedef std::vector<int>::const_iterator Input_iterator;
int sum(Input_iterator first, Input_iterator last)
{
typedef std::tuple<Input_iterator, Input_iterator> Lookup_key;
typedef std::map<Lookup_key, int> Lookup_table;
static Lookup_table lookup_table;
Lookup_table::iterator lookup_it = lookup_table.find(lookup_key);
if (lookup_it != lookup_table.end())
return lookup_it->second;
...
}
이것은 깨끗해 보이지만 여전히 읽을 수 있습니까?
언제 typedef를 사용해야합니까? 악몽 유형이 되 자마자? 그것이 두 번 이상 발생하자마자? 어디에 두어야합니까? 함수 시그니처에 사용하거나 구현에 유지해야합니까?
답변
마지막 예제는 읽기가 쉽지만 typedef를 정의한 위치에 따라 다릅니다. 로컬 범위 typedef는 (두 번째 예에서와 같이) 거의 항상 승리입니다.
나는 여전히 세 번째 예제를 가장 좋아하지만 이름 지정에 대해 생각하고 컨테이너의 의도를 알려주는 반복자 이름을 지정할 수 있습니다.
다른 옵션은 템플릿을 함수에서 만들어 다른 컨테이너에서도 작동하도록하는 것입니다. 라인을 따라
template <typename Input_iterator> ... sum(Input_iterator first, Input_iterator last)
이는 또한 STL의 정신에도 있습니다.
답변
typedef
a를 함수와 동등한 변수 선언으로 생각하십시오 .
- … 동일한 유형을 재사용 할 때 반복하지 않아도됩니다 (처음 두 예제 에서처럼).
- … 유형의 세부 사항을 숨겨서 항상 표시되지 않을 수 있습니다.
- … 유형에 대한 변경 사항이 사용되는 모든 장소에 반영되도록하십시오.
개인적으로, 긴 타입의 이름을 std::vector<int>::const_iterator
반복해서 읽어야한다면 글씨를 쓰게됩니다 .
세 번째 예제는 불필요하게 반복되지 않으며 읽기가 가장 쉽습니다.
답변
typedef
선언은 본질적으로 캡슐화와 같은 목적으로 사용됩니다. 따라서 클래스와 동일한 명명 규칙에 따라 거의 항상 헤더 파일에 가장 적합합니다.
- 당신이 필요하다면
typedef
, 특히 인수에서 사용되는 예제에서와 같이 호출자가 할 가능성이 있습니다. - 수업을 자신의 수업으로 교체하는 것을 포함하여 어떤 이유로 든 유형을 변경해야하는 경우 한 곳에서만 수행하면됩니다.
- 복잡한 유형을 반복해서 작성하기 때문에 실수가 덜 발생합니다.
- 불필요한 구현 세부 사항을 숨 깁니다.
제쳐두고, 메모 코드는 다음과 같이 더 추상화하면 훨씬 더 깨끗합니다.
if (lookup_table.exists(first, last))
return lookup_table.get(first, last);