检查是否已实例化类模板?

时间:2015-10-31 15:35:05

标签: c++ templates c++11 instantiation

是否有一种简单的方法可以查看某个类是否已在翻译单元中实例化? C ++ Primer的练习询问每个带标签的语句,是否发生了实例化:

template <typename T> class Stack { };
void f1(Stack<char>); // (a)
class Exercise {
    Stack<double> &rsd; // (b)
    Stack<int> si; // (c)
};
int main() {
    Stack<char> *sc; // (d)
    f1(*sc); // (e)
    int iObj = sizeof(Stack< string >); // (f)
}

我不确定如何才能真正检查我的答案。我想也许我可以为每个类类型使用显式实例化(例如extern template class Stack<char>),然后在程序中永远不会有相应的显式实例化定义。这样,如果事情被实例化,如果定义后来没有出现,那么链接器就会出错。

但是编译器/链接器并不总是识别出这样的错误:

template <typename T> class A{ };
extern template class A<int>;
int main(){
    A<int> a; 
}

这在gcc 4.9.2上编译得很好。但是,如果这是我程序中唯一的目标文件,那么从N3337的[14.7.2] [11]我可以看出它应该是一个错误:

  

如果实体是同一翻译单元中的显式实例化声明和显式实例化定义的主题,则该定义应遵循声明。作为主体的实体   一个显式的实例化声明,并且也会以一种方式使用,否则会导致翻译单元中的隐式实例化(14.7.1),这应该是程序中某个地方的显式实例化定义的主题;否则程序结构不合理,无需诊断。

(我猜测“不需要诊断”是为什么这不会引起错误?)。或者,只要不完整的类类型不适用于表达式,就会发生实例化 - 这样我就可以通过删除Stack的定义进行检查了吗?

template <typename T> class Stack;

这样每个不完整的类型错误都对应于实例化发生的地方?

1 个答案:

答案 0 :(得分:0)

您可以在可执行文件上使用nm工具。这将显示哪个文件包含函数定义。 gcc还提供了一个标志,用于在执行链接时去除未使用的函数。

使用“-fdata-sections”编译以将数据保存在单独的数据部分和“-ffunction-sections”中以将函数保存在单独的部分中,因此如果未使用它们(数据和函数)可以被丢弃。 链接“-gc-sections”以删除未使用的部分。