C++ 模板<;无符号整数N>;什么意思?
声明模板时,我习惯于使用这种代码:C++ 模板<;无符号整数N>;什么意思?,c++,templates,C++,Templates,声明模板时,我习惯于使用这种代码: template <class T> 模板 但是,他们使用: template <unsigned int N> 模板 我检查了它是否编译。但这意味着什么?它是非类型参数吗?如果是这样的话,我们怎么能有一个没有任何类型参数的模板呢?完全可以在整数而不是类型上模板类。我们可以将模板化的值分配给变量,或者以可能与任何其他整型文字一起使用的方式对其进行操作: unsigned int x = N; 事实上,我们可以创建在编译时进行计
template <class T>
模板
但是,他们使用:
template <unsigned int N>
模板
我检查了它是否编译。但这意味着什么?它是非类型参数吗?如果是这样的话,我们怎么能有一个没有任何类型参数的模板呢?完全可以在整数而不是类型上模板类。我们可以将模板化的值分配给变量,或者以可能与任何其他整型文字一起使用的方式对其进行操作:
unsigned int x = N;
事实上,我们可以创建在编译时进行计算的算法(从):
模板
结构阶乘
{
枚举{value=N*阶乘::值};
};
模板
结构阶乘
{
枚举{值=1};
};
//阶乘::值==24
//阶乘::值==1
void foo()
{
int x=阶乘::值;//==24
int y=阶乘::值;//==1
}
基于“unsigned int”对类进行模板化
例如:
template <unsigned int N>
class MyArray
{
public:
private:
double data[N]; // Use N as the size of the array
};
int main()
{
MyArray<2> a1;
MyArray<2> a2;
MyArray<4> b1;
a1 = a2; // OK The arrays are the same size.
a1 = b1; // FAIL because the size of the array is part of the
// template and thus the type, a1 and b1 are different types.
// Thus this is a COMPILE time failure.
}
模板
类MyArray
{
公众:
私人:
双精度数据[N];//使用N作为数组的大小
};
int main()
{
MyArray a1;
MyArray a2;
myb1阵列;
a1=a2;//好,数组大小相同。
a1=b1;//失败,因为数组的大小是
//模板,因此类型a1和b1是不同的类型。
//因此,这是编译时失败。
}
是,它是非类型参数。可以有几种模板参数
- 类型参数。
- 类型
- 模板(仅类和别名模板,无函数或变量模板)
- 非类型参数
- 指针
- 参考资料
- 积分常数表达式
template<typename T>
struct Container {
T t;
};
// pass type "long" as argument.
Container<long> test;
template<unsigned int S>
struct Vector {
unsigned char bytes[S];
};
// pass 3 as argument.
Vector<3> test;
模板
结构容器{
T;
};
//传递类型“long”作为参数。
容器试验;
模板整数参数:
template<typename T>
struct Container {
T t;
};
// pass type "long" as argument.
Container<long> test;
template<unsigned int S>
struct Vector {
unsigned char bytes[S];
};
// pass 3 as argument.
Vector<3> test;
模板
结构向量{
无符号字符字节[S];
};
//将3作为参数传递。
病媒试验;
模板指针参数(将指针传递给函数)
模板
结构函数包装器{
静态void调用_it(){F();}
};
//函数的传递地址作为参数进行传递。
void do_it(){}
功能包装试验;
模板引用参数(传递整数)
模板
结构SillyExample{
静态void do_it(){A=10;}
};
//传递标志作为参数
int标志;
典型试验;
模板参数
template<template<typename T> class AllocatePolicy>
struct Pool {
void allocate(size_t n) {
int *p = AllocatePolicy<int>::allocate(n);
}
};
// pass the template "allocator" as argument.
template<typename T>
struct allocator { static T * allocate(size_t n) { return 0; } };
Pool<allocator> test;
模板
结构池{
无效分配(大小\u t n){
int*p=AllocatePolicy::allocate(n);
}
};
//将模板“分配器”作为参数传递。
模板
结构分配器{static T*allocate(size_T n){返回0;};
水池试验;
不可能使用没有任何参数的模板。但是不带任何显式参数的模板是可能的-它有默认参数:
template<unsigned int SIZE = 3>
struct Vector {
unsigned char buffer[SIZE];
};
Vector<> test;
模板
结构向量{
无符号字符缓冲区[大小];
};
病媒试验;
语法上,template
保留用于标记显式模板专门化,而不是不带参数的模板:
template<>
struct Vector<3> {
// alternative definition for SIZE == 3
};
模板
结构向量{
//尺寸==3的替代定义
};
模板类就像一个宏,只是没有那么邪恶
将模板视为宏。使用模板定义类(或函数)时,模板的参数将替换为类(或函数)定义
不同之处在于参数具有“类型”,并且在编译过程中会检查传递的值,就像函数的参数一样。有效的类型是您的常规C++类型,如int和char。实例化模板类时,将传递指定类型的值,并且在模板类定义的新副本中,无论原始定义中的参数名称在何处,该值都将被替换。就像宏一样
您还可以使用“类
”或“类型名
”作为参数类型(它们实际上是相同的)。使用这些类型之一的参数,可以传递类型名称而不是值。就像以前一样,模板类定义中的所有参数名称,只要创建一个新实例,就会变成您传递的任何类型。这是模板类最常用的用法;了解C++模板的人都知道如何做到这一点。
考虑以下模板类示例代码:
#include <cstdio>
template <int I>
class foo
{
void print()
{
printf("%i", I);
}
};
int main()
{
foo<26> f;
f.print();
return 0;
}
#包括
模板
福班
{
作废打印()
{
printf(“%i”,i);
}
};
int main()
{
福福;
f、 打印();
返回0;
}
它的功能与使用以下代码的此宏相同:
#include <cstdio>
#define MAKE_A_FOO(I) class foo_##I \
{ \
void print() \
{ \
printf("%i", I); \
} \
};
MAKE_A_FOO(26)
int main()
{
foo_26 f;
f.print();
return 0;
}
#包括
#定义MAKE_A_FOO(I)类FOO#I\
{ \
作废打印()\
{ \
printf(“%i”,i)\
} \
};
做阿福(26)
int main()
{
福乌26楼;
f、 打印();
返回0;
}
当然,模板版本更安全、更灵活。Johannes,模板是否在“类型”下归档?我以为它们是可以生成类型的基础,但不是类型本身?@sbi看到了解释:“在标准中查找之后,我不得不将类模板上移到类型部分——尽管模板不是类型。但它们被称为类型参数,用于描述这些类型。”。14.1/2的脚注126是这样说的。只是
#include <cstdio>
#define MAKE_A_FOO(I) class foo_##I \
{ \
void print() \
{ \
printf("%i", I); \
} \
};
MAKE_A_FOO(26)
int main()
{
foo_26 f;
f.print();
return 0;
}