cpp08

YP J·2022년 6월 25일
0

CppModule

목록 보기
9/9

ex00

STL

container

iterator 객체

easyfind 함수


ex01

stack iterator

  • stack, queue, vector등 deque 기반 컨테이너들은 iterator가 없음,
  • 내부 요소에는 오직 pop,push만으로만 접근함. 그 이외의 방법으로 내부의 데이터 꺼내올 수 없음
  • list기반 컨테이너가 iterator를 가지고 있음

typedef typename

  • 만약 위의 STL iterator 예제에서 typename 키워드 없이 T::const_iterator pos; 만으로 선언을 했다면,
  • 컴파일러는 const_iterator가 T 클래스 내부의 멤버변수일거라고 생각해버릴 수도 있다.
  • 아니, 컴파일러는 이런 경우 기본적으로 타입이 아니라고 가정한다.
  • 따라서 c++ 컴파일러에게 어떤 키워드는 typedef로 재정의 된 type이라는 것을 알려주기 위해 typename 키워드를 사용해야한다.
  • iterator가 vector의 의존타입이기 때문에 iterator가 type이라는걸 알려주기 위해 typename 키워드를 사용해야한다.

  • 템플릿 매개변수를 선언하는 경우 class 및 typename을 사용한다.
  • typename은 템플릿 내부에서 허용되는 키워드이며,
  • 유형 자체가 템플릿 유형 매개변수에 따라 달라지면 그 부유형(subtype)을 참조할 때마다 typename키워드를 붙여야 한다.
  • 붙이지 않으면 일반적으로 template에서는 값이라고 인식한다.
  class A {
public:
  const static int t = 1;
};

class B {
public:
  using t = int;
};

template <typename T>
int func() {
  T::t* p;
}

func<A>()
func<B>()
  • 위와 같은 템플릿 함수에서 저 문장을 해석할 때 만약에 클래스 A에 대해서, func함수를 특수화 한다면, t가 어떠한 int값이 되어서
  T::t* p;
  • 위 문장은 단순히 클래스 A 의 t 와 p 를 곱하는 식으로 해석이 됩니다.

  • 반면에 func 함수가 클래스 B 에 대해서 특수화 된다면,

  T::t* p;
  • 이 문장은 int형 포인터 p를 선언하는 꼴이 되겠지요.

  • 따라서 컴파일러가 이 두 상황을 명확히 구분하기 위해 저 T::t가 타입인지 아니면 값인지 명확하게 알려줘야만 합니다.

  • 이렇게 템플릿 인자에 따라서 어떠한 타입이 달라질 수 있는 것을 의존 타입(dependent type) 이라고 부릅니다.

  • 따라서 컴파일러가 성공적으로 해석하기 위해서는 우리가 반드시 "야 저건 는 무조건 타입이야" 라고 알려주어야만 합니다.
    typename T::t* p;

ex)

  #include <iostream>

class A {
public:
	const static int t = 2;
};

class B {
public:
	using t = int;
};

template <typename T>
void func() {
	typename T::t *p;
	std::cout << p << std::endl;
}

template <>
void func<A>() {
	int p = 10;
	std::cout << A::t *p << std::endl;
}

int main(void) {
	A a;
	B b;
	func<A>();
	func<B>();
	return (0);
}

ex02

  template<class _Ty,
	class _Container = deque<_Ty> >
	class stack
	{ 
    // ...
    
    protected:
	_Container c;	// the underlying container
};
  • 코드를 보면 protected 접근권한자로 _Container 타입의 c 멤버변수가 있고 _Container 타입은 deque<_Ty>와 같다.

  • 따라서, c 멤버변수로는 deque의 함수를 호출할 수 있고 stack을 상속받아 c 변수로 접근가능하다면 deque의 함수들을 사용할 수 있다.

profile
be pro

0개의 댓글