为什么未调用的模板类成员未实例化?

时间:2012-06-28 20:28:17

标签: c++ class templates

我想知道当我使用指定模板类型参数创建类模板的实例时 1)为什么非被调用的函数没有被实例化? 。
2)直到我尝试使用它们才编译? 3)这种行为背后的逻辑是什么?

示例

template <class T>
class cat{
public:

T a;
void show(){
   cout << a[0];
}
void hello(){
   cout << "hello() get called \n";
}
}; 

int main(){
cat<int> ob1; // I know that show() did not get instatiated, otherwise I will get an    error since a is an int
ob1.hello();

 }

4 个答案:

答案 0 :(得分:6)

模板不是代码 - 它们是用于制作实际代码的模式。在提供参数之前模板不完整,因此无法提前创建代码。如果不使用一组特定的模板参数调用函数,则永远不会生成代码。

答案 1 :(得分:3)

如果他们实例化了整个班级,那么你可能会得到无效的代码。

你并不总是那么想。

为什么呢?因为在C ++中,它是困难(在某些情况下,根据我所知,完全不可能),“只有在X,Y和Z为真时才编译此代码”。

例如,您如何说,“只有我的复制构造函数,如果可以复制嵌入对象”?据我所知,你不能。

所以他们只是让他们不能编译,除非你真的打电话给他们。

答案 2 :(得分:3)

更多点缀:这通常称为duck typing,底线是它允许您编写“类模式”,其中某些成员函数在实例化时可能会应用使用一种模板类型时,其他成员可以在使用第二种模板类型进行实例化时应用,并且只需要实际调用的那些进行编译,您可以编写更少的代码用于最终的操作常见的。

通过不要求编译所有成员函数,您可以获得实际编译的函数的静态类型检查的所有细节。

例如,假设你有:

  template <typename E> 
  class myContainer {

      // Imagine that constructors, setup functions, etc. were here

      void sort();   // this function might make sense only if E has an operator< defined

      E max();   // compute the max element, again only makes sense with a operator<

      E getElement(int i);  // return the ith element

      E transmogrify();  // perhaps this operation only makes sense on vectors
  };

然后你有

  // sort() and getElement() makes total sense on this, but not transmogrify()
  myContainer<int> mci;         

  // sort and max might not be needed, but getElement() and transmogrify() might
  myContainer<vector<double>> mcvd;        

答案 3 :(得分:2)

没有为cat<int>::show()生成代码,因为您从未调用它。如果您确实调用它,您将收到编译错误。永远不会调用的模板函数不存在。

模板只不过是测试替换机制。这使他们非常强大。作为程序员,您可能想要创建一个cat<int>知道您永远不会调用show()或调用任何其他无效的内容。编译器让你知道你是否这样做,所以它很好用。

所以,如果你的问题是“为什么会这样”,我会问你“为什么不”?这是一个设计选择。这个选择允许我安全地使用模板类型,并且仍然可以从代码的其他部分中受益。有什么危害?你也生成更少的代码,这是一件好事,对吗?