typedef와 typename
typedef
타입의 새로운 별칭을 정의하는 키워드
typedef struct 구조체이름 {
자료형 멤버이름;
} 구조체별칭;
typedef는 클래스 안에서 타입의 새로운 별칭을 지을 수 있다.
class MyTypeClass
{
public:
typedef int Type1;
};
int main()
{
MyTypeClass a;
MyTypeClass::Type1 b;
return 0;
}
a는 MyTypeClass의 객체, b는 int 변수이다.
class MyTypeClass
{
public:
typedef int Type1;
private:
typedef double Type2;
};
int main()
{
MyTypeClass a;
MyTypeClass::Type1 b;
MyTypeClass::Type2 c; //에러
return 0;
}
타입선언이 private로 선언되어 있으면 사용하는 것도 내부적으로 사용해야함.
->typedef은 클래스 안에서도 타입의 별칭을 만들 수 있을 뿐 아니라 외부접근 제한 까지 영향을 받는다.
템플릿 파라미터로 받은 데이터 타입이 필요할 때
#include <iostream>
template<typename T>
class MyTempClass
{
public:
typedef T TempType;
};
int main()
{
MyTempClass<int> a;
MyTempClass<int>::TempType b;
MyTempClass<double> c;
MyTempClass<double>::TempType d;
return 0;
}
타입 안 타입의 객체를 호출 할 수 있다. 이렇게 템플릿 매개변수에 종속된 것을 의존 이름(dependent name) 이라고 한다. 클래스안에 중첩된 경우가 있는데 중첩 의존 이름(nested dependent name) 이라고 한다.
ex) STL의 반복자 (C++ Standard Library 예제)
컨테이너를 받아서 처음부터 끝까지 루프 돌며 모든 원소를 출력하는 코드.
template <class T>
inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="")
{
typename T::const_iterator pos;
// typename 키워드는 다음에 언급합니다
std::cout << optcstr;
for (pos=coll.begin(); pos!=coll.end(); ++pos) {
std::cout << *pos << ' ';
}
std::cout << std::endl;
}
컨테이너가 벡터, 리스트, 데크 인지도 알 수 없지만 컨테이너 원소가 int, double, char 형인지 도 알 수 없다. 하지만 각 컨테이너 안에 상수반복자를 typedef 키워드로 const_iterator 라고 정의 했기에 어떤 원소를 담은 어떤 컨테이너가 들어와도 함수가 동작 할 수 있다.
+typedef 이름 관례: typedef로 새로운 이름을 만들 떄 원래 그 멤버 이름과 똑같이 짓는 것이 관례이다.
typedef 장점
- 입력과 읽기가 편하다.
- 의사 전달이 가능하다.
ex)
int x;
int y;
y = x * 3; //문제는 없다.
typedef int Inches;
typedef int Dollars;
Inches x;
Dollars y;
y = x * 3; //의사 전달이 쉽다.
- 호환성을 높여준다.
-플랫폼에 따라서 이름을 달리 써야 하는 경우나 호환이 안되는 이름에 대해서 typedef를 사용하면 새로운 플랫폼으로 옮기는 작업이 간편해진다.
ex)
#if defined USING_COMPILER_A
typedef __int32 Int32;
typedef __int64 Int64;
#elif deined USING_COMPILER_B
typedef int Int32;
typedef long long Int64;
#endif
- 유연성이 생긴다.
-typedef 된 이름이 한 곳에서 바꾸는 것이 코드 전체를 찾아서 이름이 쓰인 곳마다 바꾸는 것보다 훨씬 간단하다.
5.특성화를 가능하게 한다. //??
-특성 이디엄(traits idiom)을 이용하면 정보에 타입을 정해줄 수 있다. 표준 컨테이너나 알고리즘을 커스터마이즈 하고자 하는 경우에는 특성을 주어야 할 때가 종종 있다.
typename
- 템플릿 매개변수(template-parameter)에 의존하는 한정된 이름(qualified-name)은 암묵적으로 하나의 형식 이름으로 간주한다.
- 기반 클래스 지정자(base-specifier)나 멤버 초기화식(mem-initializer) 에서는 사용할 수 없다.
템플릿 타입 매개변수를 선언할 때는 class와 typename의 뜻 차이가 없다. c++의 관점에서 보면 템플릿 매개변수를 선언하는 경우의 class 와 typename은 완전히 같은 의미이다.
typename 키워드의 기능
ex) 잘못된 코드
template <typename T>
class MyTypeClass
{
public:
typedef T A;
static int B;
class C{};
static void D( void ){}
};
void foo()
{
...
MyTypeClass<int>::A *E; //1번 = 하위 타입인 A의 포인터 변수 E를 선언
MyTypeClass<int>::B *F; //2번 = 정적 변수 B와 변수 F를 곱셈하는 코드
MyTypeClass<int>::C *G; //3번 = 하위 클래스 C의 포인트 변수 G를 선언
MyTypeClass<int>::D *H; //4번 = 정적 함수 D와 변수 H를 곱셈하는 코드
}
코드 타입이 똑같다. 그렇기 때문에 c++에서는 'A는 타입이야' 라고 알려주기 위해 typename을 사용한다.
void foo()
{
...
typename MyTypeClass<int>::A *C; //1번
MyTypeClass<int>::B *D; //2번
}
출처
Author And Source
이 문제에 관하여(typedef와 typename), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@songtofu/typedef와-typename저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)