C++템 플 릿 기본 편(1):함수 템 플 릿 상세 설명

Template 가 대표 하 는 일반적인 프로 그래 밍 은 C+언어 에서 중요 한 구성 부분 입 니 다.저 는 몇 편의 블 로 그 를 통 해 반년 동안 의 학습 에 대해 체계 적 인 정 리 를 할 것 입 니 다.본 고 는 기초 편의 첫 번 째 부분 입 니 다.
왜 범용 프로 그래 밍 이 있어 야 합 니까?
C++는 강 한 형식 언어 이기 때문에 동적 언어(python javascript)처럼 일반적인 논 리 를 만 들 수 없습니다.임의의 형식의 변 수 를 전송 하여 처리 할 수 있 습 니 다.범 형 프로 그래 밍 은 이 단점 을 보완 하고 유 니 버 설 논 리 를 모델 로 디자인 함으로써 유형의 제한 에서 벗 어 나 계승 체제 이외 의 또 다른 추상 적 인 체 제 를 제공 하여 코드 의 실용성 을 크게 향상 시 켰 다.
메모:템 플 릿 정의 자 체 는 컴 파일 에 참여 하지 않 고 컴 파일 러 는 템 플 릿 사용자 가 템 플 릿 을 사용 할 때 제공 하 는 형식 매개 변수 에 따라 코드 를 생 성하 고 컴 파일 합 니 다.이 과정 을 템 플 릿 예화 라 고 합 니 다.사용자 가 서로 다른 유형의 파 라 메 터 를 제공 하면 서로 다른 코드 를 예화 할 것 이다.
함수 템 플 릿 정의
서로 다른 유형의 공공 논 리 를 함수 로 추상 화하 면 함수 템 플 릿 을 얻 을 수 있다.
함수 템 플 릿 은 inline 이나 constexpr 로 설명 할 수 있 습 니 다.template 에 두 고 값 을 되 돌려 주기 전에 사용 하면 됩 니 다.
일반 함수 템 플 릿
다음은 compare 라 는 함수 템 플 릿 을 정의 합 니 다.다양한 종류의 일반적인 비교 논 리 를 지원 합 니 다.

template<typename T>
int compare(const T& left, const T& right) {
  if (left < right) {
    return -1; 
  }
  if (right < left) {
    return 1; 
  }
  return 0;
}

compare<int>(1, 2); //      
구성원 함수 템 플 릿
일반 함수 뿐만 아니 라 클래스 의 구성원 함수 도 템 플 릿 으로 정의 할 수 있 습 니 다.

class Printer {
public:
  template<typename T>
  void print(const T& t) {
    cout << t <<endl;
  }
};

Printer p;
p.print<const char*>("abc"); //  abc
왜 멤버 함수 템 플 릿 은 가상 함수(virtual)가 될 수 없 습 니까?
이것 은 c+copiler 가 parse 와 같은 클래스 에 있 을 때 vtable 의 크기 를 확인 해 야 하기 때 문 입 니 다.만약 에 하나의 가상 함수 가 템 플 릿 함수 라 는 것 을 허용 한다 면 copiler 는 parse 와 같은 종류 전에 모든 코드 를 스 캔 하여 이 템 플 릿 구성원 함수 의 호출(실례 화)을 찾 아야 vtable 의 크기 를 확인 할 수 있 습 니 다.이것 은 불가능 합 니 다.현재 copiler 의 작업 체 제 를 바 꾸 지 않 는 한
실제 적 으로 추론 하 다.
편리 하 게 사용 하기 위해 함수 템 플 릿 에 유형 파 라 메 터 를 직접 지정 하 는 것 을 제외 하고 우 리 는 컴 파일 러 가 함수 에 전달 하 는 실제 인삼 에서 유형 파 라 메 터 를 추정 할 수 있 습 니 다.이 기능 은 템 플 릿 실제 인삼 추정 이 라 고 합 니 다.
어떻게 사용 합 니까?

compare(1, 2); //  T    int
compare(1.0, 2.0); //  T    double
p.print("abc"); //  T    const char*
재 미 있 는 것 은 함수 템 플 릿 의 값 을 지정 한 형식의 함수 포인터 에 부여 하여 컴 파일 러 가 이 포인터 의 유형 에 따라 템 플 릿 의 실제 참 조 를 추정 할 수 있 도록 하 는 것 이다.

int (*pf) (const int&, const int&) = compare; //  T    int
반환 값 형식 도 매개 변수 일 때
템 플 릿 함수 의 반환 값 형식 이 다른 템 플 릿 매개 변수 로 표시 되 어야 할 때 실제 매개 변 수 를 이용 하여 모든 유형의 매개 변 수 를 가 져 올 수 없습니다.이 때 두 가지 해결 방법 이 있 습 니 다.
반환 값 형식 은 매개 변수 형식 과 전혀 무관 합 니 다.지정 한 반환 값 형식 을 표시 하고 다른 유형 은 실제 참조 에 맡 깁 니 다.
주의:이 행 위 는 함수 의 기본 실제 인삼 과 같 습 니 다.우 리 는 왼쪽 에서 오른쪽으로 하나씩 지정 해 야 합 니 다.

template<typename T1, typename T2, typename T3>
T1 sum(T2 v2, T3 v3) {
 return static_cast<T1>(v2 + v3);
}

auto ret = sum<long>(1L, 23); //  T1, T2 T3        

template<typename T1, typename T2, typename T3>
T3 sum_alternative(T1 v1, T2 v2) {
 return static_cast<T1>(v1 + v2);
}
auto ret = sum_alternative<long>(1L, 23); //error,          
auto ret = sum_alternative<long,int,long>(1L,23); //ok,         T3        ?
반환 값 형식 은 매개 변수 형식 에서 얻 을 수 있 습 니 다.그러면 함 수 를 끝 에 되 돌아 오 는 형식 으로 쓰 면 실 참 을 즐겁게 사용 하여 추정 할 수 있 습 니 다.

template<typename It>
auto sum(It beg, It end) -> decltype(*beg) {
 decltype(*beg) ret = *beg;
 for (It it = beg+1; it != end; it++) {
   ret = ret + *it;
 }
 return ret;
}

vector<int> v = {1, 2, 3, 4};
auto s = sum(v.begin(), v.end()); //s = 10
실제 추정 시의 자동 형식 변환
컴 파일 러 가 템 플 릿 실 삼 추정 을 할 때 실 삼 에 대해 유형 전환 을 하지 않 고 다음 과 같은 몇 가지 상황 만 예외 입 니 다.
  • 일반 대상 에 게 const 참조 int a=0;->const T&
  • 배열 이름 을 헤드 포인터 int a[10]={0}로 변환 합 니 다.->T*
  • 함수 명 을 함수 포인터 void func(int a){...}->T*로 변환 합 니 다.
     함수 템 플 릿 다시 불 러 오기
    함수 템 플 릿 사이 에 함수 템 플 릿 과 일반 함수 사이 에 다시 불 러 올 수 있 습 니 다.컴 파 일 러 는 호출 할 때 제공 하 는 함수 매개 변수 에 따라 이 유형의 가장 특수 한 버 전 을 처리 할 수 있 습 니 다.특수성 에 있어 서 일반적으로 다음 과 같은 순서에 따라 고려한다.
    일반 함수
  • 특수 템 플 릿(T 의 형식 을 한정 한 지침,인용,용기 등)
  • 일반 템 플 릿(T 에 대해 아무런 제한 이 없 음)어떤 템 플 릿 이 더욱 특수 하 다 고 판단 하 는 지 에 대해 원칙 은 다음 과 같다.만약 에 템 플 릿 B 의 모든 인 스 턴 스 가 템 플 릿 A 를 실례 화 할 수 있 고 반대로 안 된다 면 B 는 A 보다 특수 하 다.
    
    template<typename T>
    void func(T& t) { //      
      cout << "In generic version template " << t << endl;
    }
    
    template<typename T>
    void func(T* t) { //    
      cout << "In pointer version template "<< *t << endl;
    }
    
    void func(string* s) { //    
      cout << "In normal function " << *s << endl;
    }
    
    int i = 10;
    func(i); //      ,                
    func(&i); //      ,          ,             
    string s = "abc";
    func(&s); //      ,                ,             
    func<>(&s); //      ,  <>          template       
    
    템 플 릿 함수 특 화
    때때로 통용 되 는 함수 템 플 릿 은 개별 유형의 문 제 를 해결 하지 못 하기 때문에 우 리 는 이것 에 대해 맞 춤 형 제작 을 해 야 한다.이것 이 바로 함수 템 플 릿 의 특 화 이다.함수 템 플 릿 의 특 화 는 모든 모델 매개 변 수 를 모두 지정 해 야 합 니 다.
    
    template<>
    void func(int i) {
      cout << "In special version for int "<< i << endl; 
    }
    
    int i = 10;
    func(i); //      
    위 에서 말 한 것 은 소 편 이 여러분 에 게 소개 한 C++Template 함수 템 플 릿 의 통합 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

    좋은 웹페이지 즐겨찾기