typedef를 언제 사용해야합니까? 행동이라고 생각합니다. typedef가없는

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의 정신에도 있습니다.


답변

typedefa를 함수와 동등한 변수 선언으로 생각하십시오 .

  • … 동일한 유형을 재사용 할 때 반복하지 않아도됩니다 (처음 두 예제 에서처럼).
  • … 유형의 세부 사항을 숨겨서 항상 표시되지 않을 수 있습니다.
  • … 유형에 대한 변경 사항이 사용되는 모든 장소에 반영되도록하십시오.

개인적으로, 긴 타입의 이름을 std::vector<int>::const_iterator반복해서 읽어야한다면 글씨를 쓰게됩니다 .

세 번째 예제는 불필요하게 반복되지 않으며 읽기가 가장 쉽습니다.


답변

typedef선언은 본질적으로 캡슐화와 같은 목적으로 사용됩니다. 따라서 클래스와 동일한 명명 규칙에 따라 거의 항상 헤더 파일에 가장 적합합니다.

  • 당신이 필요하다면 typedef, 특히 인수에서 사용되는 예제에서와 같이 호출자가 할 가능성이 있습니다.
  • 수업을 자신의 수업으로 교체하는 것을 포함하여 어떤 이유로 든 유형을 변경해야하는 경우 한 곳에서만 수행하면됩니다.
  • 복잡한 유형을 반복해서 작성하기 때문에 실수가 덜 발생합니다.
  • 불필요한 구현 세부 사항을 숨 깁니다.

제쳐두고, 메모 코드는 다음과 같이 더 추상화하면 훨씬 더 깨끗합니다.

if (lookup_table.exists(first, last))
    return lookup_table.get(first, last);


답변