在声明模板时,我习惯使用这种代码:
template
但在这个问题中,他们使用了:
template
我查看它编译.但是这是什么意思?它是非类型参数吗?如果是这样,我们怎么能有一个没有任何类型参数的模板?
是的,它是一个非类型参数.您可以拥有多种模板参数
类型参数.
类型
模板(只有类和别名模板,没有函数或变量模板)
非类型参数
指针
参考
积分常量表达式
你拥有的是最后一种.它是一个编译时常量(所谓的常量表达式),是整数或枚举类型.在标准中查找之后,我不得不将类模板移动到类型部分 - 即使模板不是类型.但它们被称为类型参数,目的是为了描述这些类型.您可以拥有指针(以及成员指针)和对具有外部链接的对象/函数的引用(可以链接到其他目标文件并且其地址在整个程序中是唯一的).例子:
模板类型参数:
templatestruct Container { T t; }; // pass type "long" as argument. Container test;
模板整数参数:
templatestruct Vector { unsigned char bytes[S]; }; // pass 3 as argument. Vector<3> test;
模板指针参数(将指针传递给函数)
templatestruct FunctionWrapper { static void call_it() { F(); } }; // pass address of function do_it as argument. void do_it() { } FunctionWrapper<&do_it> test;
模板引用参数(传递整数)
templatestruct SillyExample { static void do_it() { A = 10; } }; // pass flag as argument int flag; SillyExample test;
模板模板参数.
template class AllocatePolicy> struct Pool { void allocate(size_t n) { int *p = AllocatePolicy::allocate(n); } }; // pass the template "allocator" as argument. template struct allocator { static T * allocate(size_t n) { return 0; } }; Pool test;
不能使用没有任何参数的模板.但是没有任何显式参数的模板是可能的 - 它有默认参数:
templatestruct Vector { unsigned char buffer[SIZE]; }; Vector<> test;
在语法上,template<>
保留用于标记显式模板特化,而不是没有参数的模板:
template<> struct Vector<3> { // alternative definition for SIZE == 3 };
完全可以在整数而不是类型上模拟类.我们可以将模板化的值赋给变量,或者以我们可能与任何其他整数文字的方式对其进行操作:
unsigned int x = N;
实际上,我们可以创建在编译时评估的算法(来自维基百科):
templatestruct Factorial { enum { value = N * Factorial ::value }; }; template <> struct Factorial<0> { enum { value = 1 }; }; // Factorial<4>::value == 24 // Factorial<0>::value == 1 void foo() { int x = Factorial<4>::value; // == 24 int y = Factorial<0>::value; // == 1 }
你基于'unsigned int'来模板化你的类.
例:
templateclass 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. }
模板类就像一个宏,只有很少的邪恶.
将模板视为宏.当您使用模板定义类(或函数)时,模板的参数将替换为类(或函数)定义.
不同之处在于参数具有"类型",并且在编译期间检查传递的值,例如函数的参数.有效的类型是常规的C++类型,如int和char.实例化模板类时,将传递指定类型的值,并在模板类定义的新副本中,此值将替换为参数名称在原始定义中的任何位置.就像一个宏.
您还可以使用参数的" class
"或" typename
"类型(它们实际上是相同的).使用其中一种类型的参数,您可以传递类型名称而不是值.就像之前一样,参数名称在模板类定义中的每个位置,只要您创建新实例,就会变成您传递的任何类型.这是模板类最常用的用法; 每个了解C++模板的人都知道如何做到这一点.
考虑这个模板类示例代码:
#includetemplate class foo { void print() { printf("%i", I); } }; int main() { foo<26> f; f.print(); return 0; }
它在功能上与使用宏的代码相同:
#include#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; }
当然,模板版本的安全性和灵活性要高出十亿倍.