编译器是否C++具有相同模板参数集的每个模板类实例生成代码?
Does C++ compiler generate code for every template class instance with the same set of template parameters?
以免考虑众所周知的编译时递归斐波那契计算。在这种特殊情况下,fibonacci<1>
(或fibonacci<20>
无关紧要(被实例化了多少次?是一次吗?如果是,编译器为我们执行动态编程算法:)
template<int n>
struct fibonacci
{
static const uint64_t value = fibonacci<n - 1>::value + fibonacci<n - 2>::value;
};
template<>
struct fibonacci<0>
{
static const uint64_t value = 0;
};
template<>
struct fibonacci<1>
{
static const uint64_t value = 1;
};
int main()
{
std::cout << fibonacci<80>::value;
}
让我们考虑另一个例子。
int main()
{
std::vector<int> v1;
std::vector<int> v2;
}
编译器C++是否为vector<int>
的两个实例生成单独的代码代码? 如果类似的vector<int>
实例位于不同的翻译单元中,该怎么办?
C++标准并不强制要求其中一个。只要完成的程序按照指定的方式运行,编译器就可以做任何事情,参见所谓的"as-if"规则(§1.9-1(。一个好的编译器不会生成不必要的代码,所以我希望它能将斐波那契示例优化为常量,将向量示例优化为向量函数的一个实现。
你在这里依赖于一种叫做"隐式实例化"的东西。显式模板实例化将是
template class fibonacci<0>;
template class fibonacci<1>;
template class fibonacci<2>;
// etc
现在,显式模板实例化的可能性允许您关闭隐式实例化:
extern template class fibonacci<0>;
extern template class fibonacci<1>;
extern template class fibonacci<2>;
// etc
为什么这很重要?这意味着编译器已经有一个相当精细的机制来处理模板实例化。要使隐式实例化正常工作,编译器必须能够检查实例化状态,因此它不会隐式实例化已显式实例化的模板。
因此,有一个"实例化状态是什么?"检查。这可能会返回"已经隐式实例化"。在这种情况下重新实例化模板将是一种悲观!
在这种特殊情况下,斐波那契<1>(或斐波那契<20>无关紧要(被实例化了多少次?
零个对象,只有一个静态(常量!(值。
跟
std::vector<int> v1;
std::vector<int> v2;
实例化为两个对象。
相关文章:
- 为什么我们不在下面给出的代码中使用指针来实例化C++的实体对象?
- 以下代码如何工作以每次为唯一调用堆栈唯一实例化模板函数?
- 在C++代码中搜索对象的实例化位置
- 生成代码(在编译时)以调用模板的每个实例化的静态函数
- 如何析构单例实例,或者为什么以下代码适用于析构函数?
- 编译器是否C++具有相同模板参数集的每个模板类实例生成代码?
- Google App Engine 会在实例休眠后缓存编译的 go 代码吗?
- 根据运行时参数避免模板实例化的代码重复
- 如何在代码中创建抽象类,让蓝图扩展它,并将该蓝图返回给代码进行实例化?
- 如何在代码中实例化 Vst3 插件?对于 vst3 主机应用
- C++:强制使用类的单独实例进行代码保护
- std::array 模板实例会占用更多的代码内存吗?
- 生成代码实例化具有不同参数的函数模板
- 将样本代码重构为类,并没有提高过载功能的实例
- 如何使用 C++11 unique_ptr实例化我的代码
- 为什么单一实例必须在以下代码中初始化
- 是否可以将对象实例移至QT项目中不同代码点的不同线程
- C 模板功能,相同类型,多个实例:共享一个相同的代码副本?即使在不同的CPP/对象文件中
- 应由库或客户端代码删除已加载库中的对象实例
- 窗口可防止多个实例代码不起作用