템플릿 콘텐츠 학습 노트 (1)

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;
}

추천

출처blog.csdn.net/qq_32783703/article/details/104583871