1. 템플릿 정의
16.1.1 기능 템플릿
각 유형에 대해 새 함수를 정의하는 대신 일반 함수 템플릿을 정의 할 수 있습니다.
우리는 할 수있어:
#include <memory>
#include <cstring>
template <typename T>
int compire(const T &v1,const T &v2)
{
if(v1<v2)
{
return -1;
}
if(v1>v2)
{
return 1;
}
return 0;
}
int main()
{
printf("%d\n",compire(1,2));
return 0;
}
클래스 템플릿
템플릿에 T라는 매개 변수가 있음을 발견했습니다.
//
// Created by root on 20-2-27.
//
#ifndef TEST_TEMPLATE_H
#define TEST_TEMPLATE_H
//
// Created by root on 20-2-27.
//
#include <vector>
template <typename T>class BlobA{
public:
typedef T value_type;
typedef typename std::vector<T>::size_type size_type;
BlobA()
{
}
int add(T a,T b)
{
return a+b;
}
};
#endif //TEST_TEMPLATE_H
호출 장소
#include <memory>
#include <cstring>
#include <iostream>
#include "template.h"
int main()
{
BlobA<int> a;
std::cout<<a.add(1,2)<<std::endl;
return 0;
}
클래스 템플릿 인스턴스화 :
클래스 템플릿을 사용할 때 템플릿 매개 변수에 바인딩 된 템플릿 인수 목록을 표시하려면 추가 정보를 제공해야한다는 것을 여러 번 보았습니다. 컴파일러는 이러한 템플릿 인수를 사용하여 이러한 특정 클래스를 인스턴스화합니다.
이 책을 보면 이렇게 쓰여진 데모가 내 의심을 불러 일으켰다.
#include <memory>
#include <cstring>
#include <iostream>
#include "template.h"
int main()
{
BlobA<int> a = {0,1,2};
std::cout<<a.add(1,2)<<std::endl;
return 0;
}
클래스를 {0,1,2}로 초기화 할 수있는 이유
원래 생성자는 여기에 오버로드됩니다.
//
// Created by root on 20-2-27.
//
#ifndef TEST_TEMPLATE_H
#define TEST_TEMPLATE_H
//
// Created by root on 20-2-27.
//
#include <vector>
template <typename T>class BlobA{
public:
typedef T value_type;
typedef typename std::vector<T>::size_type size_type;
BlobA()
{
}
BlobA(std::initializer_list<T> il)
{
}
int add(T a,T b)
{
return a+b;
}
};
#endif //TEST_TEMPLATE_H
다음은 사용자 지정 형식에 initializer_list를 사용하는 방법에 대한 간략한 설명입니다.
C ++ 11은 사용자가 사용자 지정 형식 (일반적으로 클래스라고 함)에서 초기화 목록을 사용하는 방법도 제공합니다.
인스턴스화 된 클래스를 살펴 보겠습니다.
BlobA (std :: initializer_list il)
{
for (auto a : il)
{
std::cout<<a<<std::endl;
}
}
결과는 0,1,2,3입니다.
우리는 책의 뒷면을 계속 읽습니다.
스마트 포인터 사용 템플릿
std::shared_ptr<BlobA<int>> data;
data는 shared_ptr의 인스턴스이고,이 shared_ptr은 T 유형의 객체의 벡터 인스턴스를 보유합니다.
1. 템플릿 정의
16.1.1 기능 템플릿
각 유형에 대해 새 함수를 정의하는 대신 일반 함수 템플릿을 정의 할 수 있습니다.
우리는 할 수있어:
#include <memory>
#include <cstring>
template <typename T>
int compire(const T &v1,const T &v2)
{
if(v1<v2)
{
return -1;
}
if(v1>v2)
{
return 1;
}
return 0;
}
int main()
{
printf("%d\n",compire(1,2));
return 0;
}
클래스 템플릿
템플릿에 T라는 매개 변수가 있음을 발견했습니다.
//
// Created by root on 20-2-27.
//
#ifndef TEST_TEMPLATE_H
#define TEST_TEMPLATE_H
//
// Created by root on 20-2-27.
//
#include <vector>
template <typename T>class BlobA{
public:
typedef T value_type;
typedef typename std::vector<T>::size_type size_type;
BlobA()
{
}
int add(T a,T b)
{
return a+b;
}
};
#endif //TEST_TEMPLATE_H
호출 장소
#include <memory>
#include <cstring>
#include <iostream>
#include "template.h"
int main()
{
BlobA<int> a;
std::cout<<a.add(1,2)<<std::endl;
return 0;
}
클래스 템플릿 인스턴스화 :
클래스 템플릿을 사용할 때 템플릿 매개 변수에 바인딩 된 템플릿 인수 목록을 표시하려면 추가 정보를 제공해야한다는 것을 여러 번 보았습니다. 컴파일러는 이러한 템플릿 인수를 사용하여 이러한 특정 클래스를 인스턴스화합니다.
이 책을 보면 이렇게 쓰여진 데모가 내 의심을 불러 일으켰다.
#include <memory>
#include <cstring>
#include <iostream>
#include "template.h"
int main()
{
BlobA<int> a = {0,1,2};
std::cout<<a.add(1,2)<<std::endl;
return 0;
}
클래스를 {0,1,2}로 초기화 할 수있는 이유
원래 생성자는 여기에 오버로드됩니다.
//
// Created by root on 20-2-27.
//
#ifndef TEST_TEMPLATE_H
#define TEST_TEMPLATE_H
//
// Created by root on 20-2-27.
//
#include <vector>
template <typename T>class BlobA{
public:
typedef T value_type;
typedef typename std::vector<T>::size_type size_type;
BlobA()
{
}
BlobA(std::initializer_list<T> il)
{
}
int add(T a,T b)
{
return a+b;
}
};
#endif //TEST_TEMPLATE_H
다음은 사용자 지정 형식에 initializer_list를 사용하는 방법에 대한 간략한 설명입니다.
C ++ 11은 사용자가 사용자 지정 형식 (일반적으로 클래스라고 함)에서 초기화 목록을 사용하는 방법도 제공합니다.
인스턴스화 된 클래스를 살펴 보겠습니다.
BlobA (std :: initializer_list il)
{
for (auto a : il)
{
std::cout<<a<<std::endl;
}
}
결과는 0,1,2,3입니다.
우리는 책의 뒷면을 계속 읽습니다.
스마트 포인터 사용 템플릿
std::shared_ptr<BlobA<int>> data;
data는 shared_ptr의 인스턴스이고,이 shared_ptr은 T 유형의 객체의 벡터 인스턴스를 보유합니다.
클래스 템플릿의 멤버 함수
클래스 템플릿 내부와 외부 모두에서 멤버 함수를 정의 할 수 있으며 템플릿에 정의 된 멤버 함수는 내향 함수로 암시 적으로 선언됩니다.
템플릿 외부에 정의 된 클래스 템플릿 멤버 함수는 템플릿으로 시작해야합니다.
항상 그렇듯이 클래스 외부에서 멤버 함수를 정의 할 때 멤버가 속한 클래스를 지정해야합니다. 템플릿 생성 클래스의 이름에는 템플릿 인수가 포함되어야합니다. 멤버 함수를 정의 할 때 멤버가 속한 클래스를 지정해야합니다. 그리고 템플릿에서 생성 된 클래스의 이름은 템플릿의 실제 매개 변수를 포함해야합니다. 멤버 함수를 정의 할 때 템플릿은 실제로 동일한 템플릿 매개 변수에 참여합니다. 멤버 함수의 경우 blob에 해당하는 멤버는 다음과 같아야합니다.
template <typename T>
ret-type Blob<T>::member-name(parm-list)
템플릿의 정의와 선언은 두 개의 파일로 분리 할 수 없습니다. 왜냐하면 특정 클래스는 컴파일 할 때 생성되지 않고 호출 될 때만 생성되기 때문입니다. 따라서 .cc를 포함해야하지만 이것은 좋은 해결책이 아닙니다. 여전히 A .h 파일로 작성됩니다.
예를 들어, 하나는 .h에 배치되고 다른 하나는 .cc에 배치됩니다.
클래스 템플릿과 다른 템플릿 간의 친근한 관계의 가장 일반적인 형태는 인스턴스와 친구간에 친근한 관계를 설정하는 것입니다.
//
// Created by root on 20-2-27.
//
#ifndef TEST_TEMPLATE_H
#define TEST_TEMPLATE_H
#include <vector>
#include <iostream>
// Created by root on 20-2-27.
//
template <typename >class BlobPtr;
template <typename >class Blob;
template <typename T>
bool operator == (const Blob<T>&,const Blob<T>&);
template <typename T>class BlobA{
public:
friend class BlobPtr<T>;
friend bool operator == <T>(const Blob<T>&,const Blob<T>&);
typedef T value_type;
typedef typename std::vector<T>::size_type size_type;
BlobA()
{
}
BlobA(std::initializer_list<T> il)
{
for (auto a : il)
{
std::cout<<a<<std::endl;
}
}
int add(T a,T b);
};
template <typename T>
int BlobA<T>::add(T a, T b) {
return a+b;
}
#endif //TEST_TEMPLATE_H
템플릿 유형 별칭
템플릿 유형의 특성, typedef BlobA data2;
또 다른 방법
별칭이 인스턴스화 된 템플릿 클래스가 아니라 템플릿임을 지정하려는 경우
template <typename T>using partNo = BlobA<unsigned>;
클래스 템플릿의 정적 멤버
다른 클래스와 마찬가지로 클래스 템플릿도 정적 멤버를 선언 할 수 있습니다.
template <typename T>class BlobA{
public:
static std::size_t count(){ return ctr;};
static std::size_t ctr;
private:
};
//初始化
template <typename T>size_t BlobA<T>::ctr = 0;
//使用
int main()
{
std::cout<<partNo<int>::count()<<std::endl;
return 0;
}
클래스 템플릿의 멤버 함수
클래스 템플릿 내부와 외부 모두에서 멤버 함수를 정의 할 수 있으며 템플릿에 정의 된 멤버 함수는 내향 함수로 암시 적으로 선언됩니다.
템플릿 외부에 정의 된 클래스 템플릿 멤버 함수는 템플릿으로 시작해야합니다.
항상 그렇듯이 클래스 외부에서 멤버 함수를 정의 할 때 멤버가 속한 클래스를 지정해야합니다. 템플릿 생성 클래스의 이름에는 템플릿 인수가 포함되어야합니다. 멤버 함수를 정의 할 때 멤버가 속한 클래스를 지정해야합니다. 그리고 템플릿에서 생성 된 클래스의 이름은 템플릿의 실제 매개 변수를 포함해야합니다. 멤버 함수를 정의 할 때 템플릿은 실제로 동일한 템플릿 매개 변수에 참여합니다. 멤버 함수의 경우 blob에 해당하는 멤버는 다음과 같아야합니다.
template <typename T>
ret-type Blob<T>::member-name(parm-list)
템플릿의 정의와 선언은 두 개의 파일로 분리 할 수 없습니다. 왜냐하면 특정 클래스는 컴파일 할 때 생성되지 않고 호출 될 때만 생성되기 때문입니다. 따라서 .cc를 포함해야하지만 이것은 좋은 해결책이 아닙니다. 여전히 A .h 파일로 작성됩니다.
예를 들어, 하나는 .h에 배치되고 다른 하나는 .cc에 배치됩니다.
클래스 템플릿과 다른 템플릿 간의 친근한 관계의 가장 일반적인 형태는 인스턴스와 친구간에 친근한 관계를 설정하는 것입니다.
//
// Created by root on 20-2-27.
//
#ifndef TEST_TEMPLATE_H
#define TEST_TEMPLATE_H
#include <vector>
#include <iostream>
// Created by root on 20-2-27.
//
template <typename >class BlobPtr;
template <typename >class Blob;
template <typename T>
bool operator == (const Blob<T>&,const Blob<T>&);
template <typename T>class BlobA{
public:
friend class BlobPtr<T>;
friend bool operator == <T>(const Blob<T>&,const Blob<T>&);
typedef T value_type;
typedef typename std::vector<T>::size_type size_type;
BlobA()
{
}
BlobA(std::initializer_list<T> il)
{
for (auto a : il)
{
std::cout<<a<<std::endl;
}
}
int add(T a,T b);
};
template <typename T>
int BlobA<T>::add(T a, T b) {
return a+b;
}
#endif //TEST_TEMPLATE_H
템플릿 유형 별칭
템플릿 유형의 특성, typedef BlobA data2;
또 다른 방법
별칭이 인스턴스화 된 템플릿 클래스가 아니라 템플릿임을 지정하려는 경우
template <typename T>using partNo = BlobA<unsigned>;
클래스 템플릿의 정적 멤버
다른 클래스와 마찬가지로 클래스 템플릿도 정적 멤버를 선언 할 수 있습니다.
template <typename T>class BlobA{
public:
static std::size_t count(){ return ctr;};
static std::size_t ctr;
private:
};
//初始化
template <typename T>size_t BlobA<T>::ctr = 0;
//使用
int main()
{
std::cout<<partNo<int>::count()<<std::endl;
return 0;
}