C++ 模板 <unsigned int N> 是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/499106/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does template <unsigned int N> mean?
提问by Igor Oks
When declaring a template, I am used to having this kind of code:
在声明模板时,我习惯了这样的代码:
template <class T>
But in this question, they used:
但是在这个问题中,他们使用了:
template <unsigned int N>
I checked that it compiles. But what does it mean? Is it a non-type parameter? And if so, how can we have a template without any type parameter?
我检查它编译。但是这是什么意思?它是非类型参数吗?如果是这样,我们如何拥有一个没有任何类型参数的模板?
回答by Johannes Schaub - litb
Yes, it is a non-type parameter. You can have several kinds of template parameters
是的,它是一个非类型参数。你可以有几种模板参数
- Type Parameters.
- Types
- Templates (only classes and alias templates, no functions or variable templates)
- Non-type Parameters
- Pointers
- References
- Integral constant expressions
- 类型参数。
- 类型
- 模板(只有类和别名模板,没有函数或变量模板)
- 非类型参数
- 指针
- 参考
- 积分常数表达式
What you have there is of the last kind. It's a compile time constant (so-called constant expression) and is of type integer or enumeration. After looking it up in the standard, i had to move class templates up into the types section - even though templates are not types. But they are called type-parameters for the purpose of describing those kinds nonetheless. You can have pointers (and also member pointers) and references to objects/functions that have external linkage (those that can be linked to from other object files and whose address is unique in the entire program). Examples:
你所拥有的是最后一种。它是一个编译时常量(所谓的常量表达式)并且是整数或枚举类型。在标准中查找之后,我不得不将类模板移到类型部分 - 即使模板不是类型。但是为了描述这些类型,它们被称为类型参数。您可以拥有指针(以及成员指针)和对具有外部链接的对象/函数的引用(那些可以从其他对象文件链接到并且其地址在整个程序中是唯一的)。例子:
Template type parameter:
模板类型参数:
template<typename T>
struct Container {
T t;
};
// pass type "long" as argument.
Container<long> test;
Template integer parameter:
模板整数参数:
template<unsigned int S>
struct Vector {
unsigned char bytes[S];
};
// pass 3 as argument.
Vector<3> test;
Template pointer parameter (passing a pointer to a function)
模板指针参数(传递指向函数的指针)
template<void (*F)()>
struct FunctionWrapper {
static void call_it() { F(); }
};
// pass address of function do_it as argument.
void do_it() { }
FunctionWrapper<&do_it> test;
Template reference parameter (passing an integer)
模板参考参数(传递一个整数)
template<int &A>
struct SillyExample {
static void do_it() { A = 10; }
};
// pass flag as argument
int flag;
SillyExample<flag> test;
Template template parameter.
模板模板参数。
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;
A template without any parameters is not possible. But a template without any explicit argument is possible - it has default arguments:
没有任何参数的模板是不可能的。但是没有任何显式参数的模板是可能的 - 它具有默认参数:
template<unsigned int SIZE = 3>
struct Vector {
unsigned char buffer[SIZE];
};
Vector<> test;
Syntactically, template<>
is reserved to mark an explicit template specialization, instead of a template without parameters:
在语法上,template<>
保留用于标记显式模板特化,而不是没有参数的模板:
template<>
struct Vector<3> {
// alternative definition for SIZE == 3
};
回答by maxaposteriori
It's perfectly possible to template a class on an integer rather than a type. We can assign the templated value to a variable, or otherwise manipulate it in a way we might with any other integer literal:
完全可以在整数而不是类型上模板化一个类。我们可以将模板化的值分配给一个变量,或者以其他任何整数文字的方式对其进行操作:
unsigned int x = N;
In fact, we can create algorithms which evaluate at compile time (from Wikipedia):
事实上,我们可以创建在编译时进行评估的算法(来自维基百科):
template <int N>
struct Factorial
{
enum { value = N * Factorial<N - 1>::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
}
回答by Martin York
You templatize your class based on an 'unsigned int'.
您根据“无符号整数”对类进行模板化。
Example:
例子:
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.
}
回答by Jonathan
A template class is like a macro, only a whole lot less evil.
模板类就像一个宏,只是少了很多邪恶。
Think of a template as a macro. The parameters to the template get substituted into a class (or function) definition, when you define a class (or function) using a template.
将模板视为宏。当您使用模板定义类(或函数)时,模板的参数会被替换为类(或函数)定义。
The difference is that the parameters have "types" and values passed are checked during compilation, like parameters to functions. The types valid are your regular C++ types, like int and char. When you instantiate a template class, you pass a value of the type you specified, and in a new copy of the template class definition this value gets substituted in wherever the parameter name was in the original definition. Just like a macro.
不同之处在于参数具有“类型”,并且在编译期间检查传递的值,就像函数的参数一样。有效类型是您的常规 C++ 类型,如 int 和 char。当你实例化一个模板类时,你传递一个你指定类型的值,并且在模板类定义的新副本中,这个值被替换在参数名称在原始定义中的任何地方。就像一个宏。
You can also use the "class
" or "typename
" types for parameters (they're really the same). With a parameter of one of these types, you may pass a type name instead of a value. Just like before, everywhere the parameter name was in the template class definition, as soon as you create a new instance, becomes whatever type you pass. This is the most common use for a template class; Everybody that knows anything about C++ templates knows how to do this.
您还可以使用 " class
" 或 " typename
" 类型作为参数(它们实际上是相同的)。使用这些类型之一的参数,您可以传递类型名称而不是值。就像以前一样,参数名称在模板类定义中的任何地方,只要您创建一个新实例,就会成为您传递的任何类型。这是模板类最常见的用途;每个了解 C++ 模板的人都知道如何做到这一点。
Consider this template class example code:
考虑这个模板类示例代码:
#include <cstdio>
template <int I>
class foo
{
void print()
{
printf("%i", I);
}
};
int main()
{
foo<26> f;
f.print();
return 0;
}
It's functionally the same as this macro-using code:
它在功能上与这个使用宏的代码相同:
#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;
}
Of course, the template version is a billion times safer and more flexible.
当然,模板版本更安全,更灵活。