我知道void指针,它们可以指向任何类型的对象。因此,如果我想要一个包含存储未知类型数据的元素的链表,我可以使用void*
:
struct Node {
Node* next;
void* data;
};
但是如果我不想使用指针但我仍然不知道Node
将携带什么类型的数据呢?有没有办法让data
没有特定的类型?我试过了auto
,但它没有用,因为它需要立即推断出初始化器。
答案 0 :(得分:4)
您想要使用模板。它们是C ++中泛型类型的一种形式。我不会在这里写完整个教程,但这里是一般形式:
template<typename T>
return_type function_name(parameters) {
}
在创建模板化对象的情况下,您可以执行以下操作:
template<typename T>
struct struct_name {
T member_name;
};
这里,“template”和“typename”是C ++中的实际关键字。 “T”可以是您想要的任何名称。
http://www.cplusplus.com/doc/tutorial/templates/
编辑:我想强调以下内容可能是C ++模板中最重要的非常重要的事情,我在提供的链接中对此进行了讨论:
因为模板是在需要时编译的,所以这会强制a 多文件项目的限制:实现(定义) 模板类或函数必须与其相同的文件 声明。这意味着我们无法将界面分开 单独的头文件,我们必须包括接口和 在任何使用模板的文件中实现。
答案 1 :(得分:2)
正如其他人所指出的那样,C ++基本上无法拥有一个在编译时未确定其类型的对象。您似乎要描述的通用概念称为类型擦除,一个透明生成您可能实际发生的任何查询所需的所有编译时类型的过程。公共图书馆是Boost.Any。现在我看到Boost还有一个更新的type erasure库,用于更广泛和更高级的用法。
类型擦除仍然需要您了解对象可能保留的类型。如果可能的话,你会从“给我一个int
这样的操作。”
模板不是一回事。模板Node<T>
将为每个T提供不同类型的节点,因此从节点形成的整个数据结构将专用于存储特定类型,而不是混合。这就是C++ standard library的工作原理,您通常应该使用它而不是编写自己的数据结构。
答案 2 :(得分:1)
由于 c ++是静态类型的,因此必须在编译时解析所有类型。并且void变量不能被删除,因为编译器不知道要分配多少内存。
可能存在运行时类型发现的错觉,但实际上这在c ++中是不可能的。基于模板的解决方案可能适用于某些perpouse。但实际上我不能在变量中保留任意类型。
答案 3 :(得分:1)
使用void*
来表示“任何(指针)类型的未知值”在C语言中很常见。但是,在C ++中,有一个更好的解决方案 - 即使用模板。
一般形式是:
template <typename T>
struct Node {
Node* next;
T data;
};
然后你会声明Node<int>
(或者你想在列表中保留的任何类型)。
模板非常强大但可能会变得非常复杂。我建议您阅读他们最喜欢的C ++教科书中的用法。