为什么不实例化未调用的模板类成员?
Why uncalled template class members aren't instantiated?
当我创建指定模板类型参数的类模板实例时,我想知道这一点。
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();
}
模板不是代码 - 它们是用于制作实际代码的模式。在提供参数之前,模板不完整,因此无法提前创建代码。如果不使用一组特定的模板参数调用函数,则永远不会生成代码。
如果他们实例化了整个类,那么你可能会得到无效的代码。
你并不总是想要这样。
为什么?因为在C++中,很难(在某些情况下,据我所知,完全不可能)说,"只有在 X、Y 和 Z 为真时才编译此代码"。
例如,你会怎么说,"如果嵌入对象可以复制,只有我的复制构造函数"?据我所知,你不能。
所以他们只是让它们不编译,除非你真的调用它们。
一点:这通常称为鸭子类型,底线是它允许您编写"类模式",当使用一种模板类型实例化时,某些成员函数可能会应用,其他成员在使用第二个模板类型实例化时可能会应用,并且只需要您实际调用的模板进行编译, 您可以为最终成为常见操作的代码编写更少的代码。
通过不要求编译所有成员函数,您可以获得对实际编译的函数进行静态类型检查的所有细节。
例如,假设您有:
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;
不会为cat<int>::show()
生成任何代码,因为您从不调用它。如果您确实调用了它,则会出现编译错误。 从不调用的模板函数不存在。
模板只不过是测试替换机制。 这使它们非常强大。 作为程序员,您可能希望创建一个cat<int>
,因为您知道您永远不会调用show()
或调用任何其他无效的内容。 编译器会让您知道您是否这样做了,因此效果很好。
因此,如果您的问题是"为什么它以这种方式工作",我会问您"为什么不"? 这是一个设计选择。 此选项允许我安全地使用模板类型,并且仍然可以从代码的其他部分中受益。 有什么危害? 你生成的代码也更少,这是一件好事,对吧?
- 静态数据成员模板专用化的实例化点在哪里
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 受约束的成员函数和显式模板实例化
- 实例化多种类型的成员函数模板
- 为什么在使用指针时不采用类成员的默认值,而不是直接实例化对象时?
- 将类成员函数的模板定义放在 CPP 文件中C++隐式实例化而不是 .H 允许吗?
- 如何实例化类的公共成员并将其作为 std::p romise 返回?
- 在实例化封闭类模板之后,我们可以声明模板类成员的部分专用化吗
- 使用 SFINAE 有选择地实例化模板的成员函数
- 静态模板成员函数的实例化?
- 访问使用接口实例化的类的私有成员
- Google Mock:在目标类的构造函数中实例化的模拟私有变量成员
- 参考数据成员到模板的实例化
- 类的私有成员在我的类实例化期间更改,即使他们不应该
- 如果未实例化成员模板,是否要评估static_asserts?
- 实例化与unique_ptr的类集合成员
- 实例化成员模板函数时的Buggy(?)编译器行为
- 使用向量<向量>成员实例化对象时的隔离错误<int>
- 静态成员与静态常量成员实例化 - 有什么区别?
- 显式类成员实例化