“编译时”已知的信息是在源代码编译成程序时编译器(以及扩展后的您)可用的信息。 这样的信息因此可以被“烘焙”到程序中,语言的某些方面被限制在这类信息中。
例如:
这与只在“运行时”才知道的事情形成对比; 这包括用户输入的值或在执行期间从文件中读取的值,但在某些情况下也可以是在源代码中编写的数据。
例如,函数int x(){return 42;}
具有硬编码的返回值,但如果您从不同的翻译单元(大致是源文件)调用x()
,编译器在编译调用时将不知道该值是硬编码的。 因为存在这种情况和其他情况,所以x()
的结果不会(也不能)被语言认为是“常量”。
(在这个简单的示例中,可以使用inline
和constexpr
来减轻它。)
请参阅以下列表:翻译阶段。 这些阶段都是作为构建可执行文件过程的一部分发生的,它们发生在可执行文件被执行之前。
“编译时间”指的是编译器处理这些阶段。 有时人们会排除阶段9(取而代之的是称之为“链接时间”),但您通常会根据上下文判断他们是否打算包括阶段9。
对于您的问题中的示例模板实例化,这发生在第8阶段。
“如果在编译时知道大小,也可以使用模板。”
这是指:你在写代码的时候就已经知道大小了。 您可以编写例如42
,因为您知道大小将是42
。 不是在编译时,例如,您知道用户提供的值。
假设您有一个
struct foo {
// holds a container of bars
};
两种选择:
您在编译时就知道容器的大小,也就是说,您在编写代码时就知道大小。 那么这是一个选项:
template <size_t size>
struct foo {
std::array<bar,size> x;
};
用法:
foo<42> f;
或者您在编译时不知道大小,即:大小只有在执行期间才知道。 则不能使用std::array
或以size为参数的模板:
struct foo {
std::vector<bar> x;
foo(size_t size) : x(size) {}
}
用法:
size_t size;
std::cin >> size;
foo f(size);