背景:由于模板代码膨胀,STL 的使用使构建速度变慢:通常相同的方法在许多不同的翻译单元中独立实例化,并被多次编译和优化。避免模板类的这种对象代码重复的一种方法是使用显式模板实例化和外部模板声明,但 STL 实现不支持它们。我正在尝试实现一个std::vector<T>
支持显式实例化的等价物。
问题:我有一个模板类,如果模板参数不满足某些条件vector<T>
,我希望删除它的一些方法。T
更糟糕的是,这里有一些额外的要求:
vector<T>
无论是否T
满足条件,都必须可以显式实例化。- 当有人调用有条件删除的方法时,应该会发出编译错误。
- 我有几个这样的条件,以及一组依赖于每个条件的方法。
讨论:例如,该方法在不可复制vector<T>::push_back(const T&)
时无法工作。T
如果我保持这个方法实现不变,那么如果我显式实例化 eg ,编译器将产生错误vector<unique_ptr<int>>
,因为它将无法复制unique_ptr<int>
. 这与要求 1 相矛盾,并使所需的代码膨胀优化变得不可能。
我可以对 进行两种不同的实现vector<T>::push_back(const T&)
,一种用于可复制构造的类型,另一种用于其他类型。这可以使用 SFINAE 重载或使用辅助模板类来完成。非复制构造案例的实现可以简单地抛出异常或调用终止。但是随后调用 for 的方法push_back
只会vector<unique_ptr<int>>
在运行时崩溃。如要求 2 所述,它不会产生编译错误。
最后,有几个条件,每个条件都排除了一些方法。该类型T
可以在各种组合中缺少以下属性:可复制构造、可复制赋值、可默认构造、可移动构造。相关问题的解决方案似乎仅适用于一种条件,不满足要求 3。
我剩下的唯一想法是使用某种整体的部分专业化vector<T>
与预处理器技巧相结合。但这需要像 16 个独立的专业,这听起来很糟糕。
PS很明显,STL 设计本质上依赖于隐式实例化的机制,这使得减少由它们引起的代码膨胀变得非常困难。