我是C ++的新手,我有一个问题。 让我们说我有一个类,函数定义和一个主要完成(here源代码):
// sequence template
#include <iostream>
using namespace std;
template <class T, int N>
class mysequence {
T memblock [N];
public:
void setmember (int x, T value);
T getmember (int x);
};
template <class T, int N>
void mysequence<T,N>::setmember (int x, T value) {
memblock[x]=value;
}
template <class T, int N>
T mysequence<T,N>::getmember (int x) {
return memblock[x];
}
int main () {
mysequence <int,5> myints;
mysequence <double,5> myfloats;
myints.setmember (0,100);
myfloats.setmember (3,3.1416);
cout << myints.getmember(0) << '\n';
cout << myfloats.getmember(3) << '\n';
return 0;
}
问题是:在template <class T, int N>
中,是否应该在编译时知道值N
(就像在这种情况下一样)?或者可以在运行时指定?
答案 0 :(得分:2)
是。所有模板参数都需要在编译时知道(其他任何事情都会导致编译器错误)。
这样做的原因是从技术上讲,mysequence<int, 1>
和mysequence<int, 2>
是完全独立的类型,由编译器生成。如果编译器以前从未见过您的N
,那么它如何为您生成类型?
编译器需要单独生成这些类型的事实也是迫使您实现模板in the header的原因。在运行时确定参数显然会更难做(您需要动态重新编译代码!)。
以下是C ++标准对模板参数(不是类型)的说法:
非类型模板参数的模板参数应为模板参数类型的转换常量表达式
现在什么是转换的常量表达式?
T类型的转换常量表达式是一个表达式,隐式转换为类型T,其中转换后的表达式是常量表达式
[对可能应用的转化的一些限制,请遵循]
实际上,它只是一个常量表达式并添加了一些转换。什么是常量表达式的规则有点复杂([expr.const]/2),但标准有一个简单的总结:
假设执行复制省略,满足这些要求的表达式称为常量表达式。 [注意:在翻译期间可以评估常量表达式。 - 尾注]
在翻译期间进行评估是一个奇特的术语,编译器可以在编译时完成。&#34;
因此,必须在编译时知道非类型模板参数(因此,请键入模板参数,尽管构建一个您希望在运行时设置类型模板参数的场景更难)