非类型模板参数是C++模板编程中的一个特性,它允许模板使用不是类型的参数。这些参数可以是整型、指向对象或函数的指针、引用等。非类型模板参数为模板提供了更大的灵活性和功能,允许基于这些参数生成不同的模板实例。
下面是一些关于非类型模板参数的要点:
基本用法
非类型模板参数的声明方式是在模板参数列表中使用一个明确的类型,后跟参数名,如下所示:
template <typename T, int Size>
class Array {
T data[Size];
public:
void print() {
for (int i = 0; i < Size; ++i) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
};
在上面的例子中,T
是一个类型模板参数,而 Size
是一个非类型模板参数。
限制
非类型模板参数有一些限制:
- 必须是常量表达式,这意味着在编译时其值必须是已知的。
- 不能使用浮点类型作为非类型模板参数。
- 可以使用指针或引用,但它们必须指向外部链接的实体或具有内部链接且在模板定义可见范围内的实体。
示例
下面是一些使用非类型模板参数的例子:
整型参数
template <int N>
class PowerOfTwo {
public:
static const int value = 1 << N;
};
// 使用
int two_to_the_fourth = PowerOfTwo<4>::value; // 结果是 16
指针参数
template <const char* message>
class Greeter {
public:
void sayHello() {
std::cout << message << std::endl;
}
};
// 使用
Greeter<"Hello, World!"> greeter;
greeter.sayHello(); // 输出 "Hello, World!"
引用参数
extern int globalVar;
template <int& REF>
class RefPrinter {
public:
void print() {
std::cout << REF << std::endl;
}
};
// 使用
RefPrinter<globalVar> printer;
printer.print(); // 输出 globalVar 的值
非类型模板参数在C++标准库中也有广泛的应用,例如在 std::array
中,它用来指定数组的固定大小。
在使用非类型模板参数时,需要注意它们的值必须在编译时可知,且需要遵守C++的类型系统规则。通过合理地使用非类型模板参数,可以创建出既灵活又高效的模板代码。
注意:
double等类型不可以作为模板参数。