다음과 같은 경우 종속 유형에 typename을 사용할 필요가없는 이유는 무엇입니까?


10

유형의 참조를 제거하는 방법에 대해 읽었 습니다 .

다음 예제를 제공합니다.

#include <iostream> // std::cout
#include <type_traits> // std::is_same

template<class T1, class T2>
void print_is_same() {
  std::cout << std::is_same<T1, T2>() << '\n';
}

int main() {
  std::cout << std::boolalpha;

  print_is_same<int, int>();
  print_is_same<int, int &>();
  print_is_same<int, int &&>();

  print_is_same<int, std::remove_reference<int>::type>(); // Why not typename std::remove_reference<int>::type ?
  print_is_same<int, std::remove_reference<int &>::type>();// Why not typename std::remove_reference<int &>::type ?
  print_is_same<int, std::remove_reference<int &&>::type>();// Why not typename std::remove_reference<int &&>::type ?
}

특성 의 types std::remove_reference는 종속 유형입니다.

가능한 구현

template< class T > struct remove_reference      {typedef T type;};
template< class T > struct remove_reference<T&>  {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};

그러나 왜 사용하지 typename std::remove_reference</*TYPE*/>::type않습니까?

답변:


22

특성 의 types std::remove_reference는 종속 유형입니다.

아니요, 여기 에는 종속적 인 이름 이 아닙니다 . 템플릿 인수는 명시 적으로 지정되어 int, int&int&&. 따라서이 시점에서 유형이 알려져 있습니다.

반면 std::remove_reference템플릿 매개 변수와 함께 사용 하는 경우

template <typename T>
void foo() {
    print_is_same<int, typename std::remove_reference<T>::type>();
}

그런 다음 표현식이 템플리트 매개 변수에 따라 달라 지므로 유형 typename임을 알려야합니다 .std::remove_reference<T>::typeT


5

간단히 말해서 typename컴파일러가

std::remove_reference<int>::type

정말 유형입니다. 다른 템플릿을 고려할 수 있습니다

template <typename T>
struct foo {
    using type = int;
};

여기 foo::type타입이 있습니다. 그러나 누군가가

template <> struct foo<int> {
    int type;
};

이제는 type유형이 아니라입니다 int. 이제 템플릿 내에서 foo를 사용할 때 :

template <typanem T> 
struct bar {
    using type = typename foo<T>::type;
};

컴파일러 foo<T>::typebar(및 기본 템플릿 foo) 컴파일러 만 볼 수 없기 때문에 실제로는 다른 유형이 아닌 컴파일러인지 확인해야합니다.

그러나 귀하의 이 유형 인 경우에 의존하지 않는 템플릿 매개 변수, 따라서 컴파일러는 쉽게 확인할 수 있습니다.mainstd::remove_reference<int>::type


0

키워드 typename 은 컴파일러가 소스를 구문 분석하는 데 도움이됩니다. ID가 변수 이름이나 메소드 이름이 아닌 유형 이름임을 나타냅니다. 그러나 위의 컴파일러와 같은 상황에서는 자체적으로 알아낼 수 있으므로이 키워드는 필요하지 않습니다.

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