c++模板进阶

在这里插入图片描述

欢迎来到Cefler的博客
博客主页:那个传说中的man的主页
个人专栏:题目解析
推荐文章:题目大解析3


目录

  • 非类型模板参数
  • 类模板的特化
  • 模板的分离编译

非类型模板参数

在 C++ 中,模板的非类型模板参数是指一些非类型值,在模板实例化时作为模板实参进行传递。它们可以是整型、浮点型、枚举类型、指针、引用等常见类型,但不能是所有类型都可以。

非类型模板参数必须在编译时就确定其值,并且定义时需要显示指定初始值。它们可以用于编译时计算和处理数据,进而实现更加泛化和高效的代码。下面是一些示例:

  1. 定义非类型模板参数(整型):
template 
class MyClass {
public:
    void print() {
        cout << "N = " << N << endl;
    }
};

// 实例化一个类
MyClass<10> obj;
obj.print();  // 输出 N = 10
  1. 定义非类型模板参数(枚举类型):
enum class Color { RED, GREEN, BLUE };

template 
class MyClass {
public:
    void print() {
        cout << "Color = " << static_cast(c) << endl;
    }
};

// 实例化一个类
MyClass obj;
obj.print();  // 输出 Color = 0
  1. 定义非类型模板参数(指针类型):
template 
class MyClass {
public:
    void print() {
       cout << "*P = " << *P << endl;
    }
};

int x = 10;
int* ptr = &x;

// 实例化一个类
MyClass<&x> obj;
obj.print();  // 输出 *P = 10

需要注意的是,对于非类型模板参数,它们必须在编译时就被确定其值。这也意味着对于指针类型的非类型模板参数,其值需要在编译时就确定,而不是在运行时才能确定,说人话就是传的参数必须是常量

总之,C++ 的非类型模板参数是一种强大的特性,可以使代码更加泛化和高效,但同时也需要谨慎使用。在实际编码中应该注意非类型模板参数的限制条件,并根据具体情况合理使用。

类模板的特化

C++ 模板的类模板特化是指对于特定类型或模板参数组合,提供一个专门实现的模板版本。类模板特化可以根据特定的需求对通用的模板进行特殊处理,以满足特定类型或模板参数的要求。

类模板特化有两种形式:完全特化(full specialization)和偏特化(partial specialization)。

  1. 完全特化(Full Specialization):
    完全特化是指为特定的类型或模板参数组合提供一个单独的模板定义。完全特化的模板定义会覆盖原始的类模板定义,针对特定的类型或模板参数进行定制化的实现。

下面是一个示例,演示了类模板 MyClass 的完全特化:

// 原始的类模板定义
template <typename T>
class MyClass {
public:
    void print() {
        cout << "Generic version" << endl;
    }
};

// 类模板的完全特化定义
template <>
class MyClass<int> {
public:
    void print() {
        cout << "Specialized version for int" << endl;
    }
};

int main() {
    MyClass<double> obj1;
    obj1.print();       // 输出 "Generic version"

    MyClass<int> obj2;
    obj2.print();       // 输出 "Specialized version for int"

    return 0;
}

在上述示例中,通过 template <>MyClass 进行了完全特化,重写了 print() 函数的实现。当使用 MyClass 类型实例化对象时,会使用完全特化的定义。

  1. 偏特化(Partial Specialization):
    偏特化是指对模板参数中的一部分进行特化,而保持另一部分为通用定义。通过偏特化,可以根据模板参数的某些属性选择不同的实现方式。

以下示例演示了类模板 Pair 的偏特化:

template <typename T, typename U>
class Pair {
public:
	Pair(T first, U second) : first(first), second(second) {}
	void print() {
		cout << "Generic version: " << first << ", " << second << endl;
	}
private:
	T first; 
		U second;
};

// 类模板的偏特化定义
template <typename T>
class Pair<int ,T> {
public:
	Pair(int first,T second) : first(first), second(second)
    {}
	void print() {
		cout << "Partial specialization for second as int: " << first << ", " << second << endl;
	}
private:
    int first;
	T second;
	
};

int main() {
	Pair<double, string> obj1(3.14, "hello");
	obj1.print();       // 输出 "Generic version: 3.14, hello"

	Pair<int, string> obj2(42, "world");
	obj2.print();       // 输出 "Partial specialization for second as int: 42, world"

	return 0;
}

在上述示例中,通过 template 中的类型参数 Ttemplate 中的类型参数 U,对 Pair 进行了偏特化。当第一个模板参数为 int 时,使用偏特化的定义。

通过类模板的特化,可以根据特定的数据类型或模板参数组合,为类模板提供专门的实现方式,增强了其灵活性和适用性。使用类模板的特化可以更好地应对复杂的应用场景和需求。

模板的分离编译

模板的分离编译是 C++ 中一种重要的编译技术,它可以提高代码的可维护性和可扩展性,同时也可以减小编译时间和程序体积。

C++ 模板的分离编译主要是针对类模板函数模板。当一个模板类或函数需要在多个源文件中使用时,为了避免重复定义和增加编译时间,可以将其分为声明和定义两部分,将声明放在头文件中,将定义放在单独的源文件中,然后在使用该模板的源文件中包含头文件即可。这样一来,每个源文件只需要编译一次模板定义,使得代码更加清晰和易于管理。

以模板类为例,下面是一个简单的示例:

// MyClass.h 头文件
#ifndef MYCLASS_H
#define MYCLASS_H

template <typename T>
class MyClass {
public:
    MyClass(T val);
    void print();
private:
    T value;
};

#include "MyClass.cpp"

#endif

// MyClass.cpp 源文件
#include "MyClass.h"
#include 

using namespace std;

template <typename T>
MyClass<T>::MyClass(T val) : value(val) {}

template <typename T>
void MyClass<T>::print() {
    cout << value << endl;
}

// main.cpp 文件
#include "MyClass.h"

int main() {
    MyClass<int> obj(42);
    obj.print();
    return 0;
}

在上述示例中,模板类 MyClass 被分为了头文件 MyClass.h 和源文件 MyClass.cpp 两部分。在头文件中声明了类模板的定义,包括类名、成员函数和变量等。在源文件中定义了类模板的成员函数和变量实现的具体代码。

然后,在使用 MyClass 的源文件 main.cpp 中,只需要包含头文件 MyClass.h 即可,编译器会根据头文件中的声明自动链接指定的源文件 MyClass.cpp

通过模板的分离编译,我们可以轻松地维护和扩展代码,同时也可大大缩短编译时间,提高程序的执行效率。


如上便是本期的所有内容了,如果喜欢并觉得有帮助的话,希望可以博个点赞+收藏+关注❤️ ,学海无涯苦作舟,愿与君一起共勉成长
c++模板进阶_第1张图片
在这里插入图片描述

你可能感兴趣的:(c++,模板)