为什么编译器忽略模板类中的struct元素?
Why does the compiler ignore struct elements inside a template class?
我正在使用g++编译器。我编写了以下代码,其中包含一个模板类定义。类有一个叫做node的结构数据类型,它的元素a和b都是泛型类型。该类有一个名为print的函数,它打印p.h,其中p是类对象的节点类型的变量。编译器没有显示任何错误,尽管'h'不是struct node的元素。为什么呢?
#include<iostream>
#include<cstdlib>
using namespace std;
template <typename e>
class mc
{
typedef struct node
{
e a,b;
}node;
node p;
public:
void print();
};
template <typename e>
void mc<e>::print()
{
std::cout<<p.h;
}
int main()
{
mc<int> m;
//m.print();
return(0);
}
只有当m.p rprint()在main中没有注释时,编译器才会显示错误。为什么呢?
如果不使用模板的对象(实例),编译器只检查模板的逻辑。模板将不会被实例化。但是,如果您尝试使用模板的实例,该模板将被实例化(扩展),那么您将看到错误,h
不是p
的成员。
也就是说,如果你注释掉//m.print()
,模板将被实例化
为了使编写template
类更容易一点,未调用的template
方法不会实例化。
检查一些事情——方法的签名,查找只涉及不依赖于类的template
参数的数据的任何方法或函数等。
在这种情况下,p
在技术上依赖于类的template
参数,因此检查p.h
是否有效是在实例化时完成的。现在,您可以证明没有e
使得p.h
是有效的,但是编译器不必这样做,所以它没有麻烦。
程序可能仍然是病态的:如果没有template
的有效专门化,标准中有条款规定程序可能是病态的(不需要诊断),但我不知道这是否适用于template
的方法。
一旦调用了print
,方法就会被实例化,错误就会被注意到。
std
库中使用这个方法的一个例子是vector
——它的一些方法,包括<
,在它的数据上盲调用<
。vector
不要求它的数据支持<
,但如果有人试图调用<
,它确实需要它。
在这种情况下,现代c++技术将涉及禁用vector::operator<
(标准讨论"不参与重载解析"),而在c++ 1z中,通过requires
子句(如果该提案被标准化),这变得容易得多。
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- C++如何通过用户输入删除列表元素
- 删除和更新矢量<struct>中的特定元素
- 元素 std::vector <struct>的更有成效的段落
- C 在结构数组中为每个元素(struct)分配堆内存
- 在struct构建的向量中添加元素
- 在向量上找到第一对元素 (int) 并得到第二对元素 (struct)
- c++中使用memset初始化具有不同值的struct数组元素
- 给struct数组中的元素赋值时出错
- 如何修改vector中的struct元素
- 如何从vector中移除struct元素
- 为什么编译器忽略模板类中的struct元素?
- c++中删除struct数组中的元素
- 在vector的每个struct元素中重置值的最快方法