서브젝트에 나온 모르는 개념들

hyenam·2022년 4월 8일
0

ft_containers

목록 보기
1/8

모르는 것들

구현 목록
• iterators_traits
• enable_if
• is_integral
• equal
• lexicographical_compare
• SFINAE

요구 사항
• namespace 만들기
• std::allocator
• friend


iterators_traits

반복자 특질?

원래는 iterator_traits인데 서브젝트에는 iterators_traits라고 표기가 되어 있다.

cplusplus에 따르면 iterator_traits반복자의 속성을 정의하는 반복자 클래스라고 한다.
반복자 관점에서 알고리즘을 구현하게 할 수 있다.

아래는 해당 페이지의 파파고 버전

표준 알고리즘은 전달된 반복자의 특정 특성과 해당 iterator_traits 인스턴스화의 멤버를 사용하여 나타내는 범위를 결정한다.

모든 반복자 유형에 대해 iterator_traits 클래스 템플릿의 해당 전문화를 정의해야 하며, 적어도 다음 멤버 유형을 정의해야 한다.

  • difference_type - 반복자 하나를 다른 반복자에서 뺀 결과를 나타냅니다.
  • value_type - 반복자가 가리킬 수 있는 요소의 유형입니다.
  • pointer - 반복자가 가리킬 수 있는 요소에 대한 포인터 유형입니다.
  • reference - 반복자가 가리킬 수 있는 요소에 대한 참조 유형입니다.
  • iterator_category - 반복자 카테고리. 다음 중 하나가 될 수 있습니다.
    • input_iterator_tag
    • output_iterator_tag
    • forward_iterator_tag
    • bidirectional_iterator_tag
    • random_access_iterator_tag

참고: 적어도 순방향 반복자가 아닌 출력 반복자의 경우, 이러한 멤버 유형 중 하나('itator_category' 제외)는 void로 정의될 수 있습니다.

'iterator_traits' 클래스 템플릿은 이러한 유형을 반복자 유형 자체에서 가져오는 기본 정의와 함께 제공됩니다(아래 참조). 또한 pointer (T)와 const(const T)에 특화되어 있다.

모든 사용자 지정 클래스는 기본 클래스 std::iterator를 공개적으로 상속하는 경우 'iterator_trates'의 유효한 인스턴스화를 가집니다.

멤버일반적 정의T* 특수화const T* 특수화
difference_typeIterator::difference_typeptrdiff_tptrdiff_t
value_typeIterator::value_typeTT
pointerIterator::pointerT*const T*
referenceIterator::referenceT&const T&
iterator_categoryIterator::iterator_categoryrandom_access_iterator_tagrandom_access_iterator_tag

SFINAE

SFINAESubstitution Failure Is Not An Error의 약어이다.

이 기능은 TMP에서 사용이 되는데, 템플릿으로 오버로딩 함수를 만들었을때 만약 인자 치환이 실패했을 경우 컴파일러는이 오류를 무시하고 오버로딩 후보에서 제외한다는 의미이다.

하지만 매번 컴파일 오류가 무시되는 것은 아니다. SFINAE는 적용범위가 한정되어 있다.

대표적인? SFINAE 유형

  • 템플릿 매개 변수 유형에 잘못된 형식이 사용됨
  • 함수 유형에 잘못된 형식이 사용됨

enable_if

c++11이후에 추가된 것으로 enable_if를 사용하면 SFINAE를 잘 사용할 수 있게 된다.

enable_if는 오버로딩 확인을 위한 형식의 인스턴스를 조건부를 만든다. enable_if를 사용하게 되면 수많은 오버로딩 템플릿들의 치환오류를 탐색하고 오류가 날 경우 오버로딩 후보군에서 제거해주는 역할을 하기 때문이다.

template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type * = 0>
void test(T &a)
{
	std::cout << "is int" << std::endl;
}

이런식으로 정의해주면 인자로 정수값이 들어왔을때만 해당 오버로딩 함수가 실행된다고 한다.

is_integral

T가 정수유형인지 여부를 식별하는 구조체 템플릿이다.

T의 정수 유형 여부에 따라 true_type, false_type으로 상속된다.

멤버 타입으로는

  • value_type - bool type
  • type - true_type인지 false_type인지
    이렇게 두개가 있다.

멤버 변수는 참인지 거짓인지 구분하는 bool타입의 value가 하나 있다.

equal

두 범위의 요소가 같은지 확인하는 함수이다.
두 범위의 요소가 같으면 true를 아니면 flase를 리턴한다.

lexicographical_compare

두 요소가 동일하지 않을 때 사전순으로 비교하게 해주는 함수이다.
아마 map구현에 사용이 될 것 같은 함수이다.

namespace 만들기

namespace [namespace name]
{
  class [class]
  {
    ...
  };
};
[namespace name]::[class name]::myFunc() { ... };

이런식으로 헤더와 cpp파일을 작성하면

#include "myHeader.hpp"
int main()
{
 [namespace]::[class] a;
}

이렇게 해당 namespace에 있는 class를 불러와 객체를 만들수 있게된다!

std::allocator

일반적으로 동적할당을 할때는 new 와 delete 를 사용하는데 STL이나 라이브러리를 작성할때는 allocator를 많이 사용한다고 한다.

메모리를 좀더 유연하고 효율적으로 사용하기 위해 allocator클래스를 상속받아 멤버함수를 오버라이드해 커스텀한다고 한다.

그래서 컨테이너들은 대부분 allocator를 사용하여 메모리를 관리한다고 한다.
뿐만 아니라 아래와 같은 장점도 지니고 있다.

  • allocator를 사용하면 초기화 되지 않은 상태의 메모리의 시작 주소를 얻을 수 있다.
  • 할당받은 메모리에 객체를 생성하고 메모리 해제 없이 객체들을 소멸시킬 수 있다.
  • 아직 초기화 되지 않은 공간을 알 수 있는 방법을 제공해준다.

friend

friend가 붙은 클래스가 friend로 선언된 다른 클래스의 private및 protected멤버에 접근 할 수 있게 해주는 키워드이다.

그런데 클래스말고 함수에도 이 키워드를 붙일 수 있다.
멤버 함수 단위로 지정을 해주게 되면 이미 정의되어 있는 함수를 자신의 클래스에 정의만 해서 사용할 수 있게 되는 것이다.

friend키워드를 명시하지 않는 이상 친구 관계가 형성되지 않고,
이미 친구 관계를 형성한 클래스의 자식 클래스고 키워드를 명시하지 않으면 친구 관계가 형성되지 않는다.


참고 사이트

profile
공부한 걸 정리하고 있습니다.

0개의 댓글

관련 채용 정보