Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板<;无符号整数N>;什么意思?_C++_Templates - Fatal编程技术网

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;
}