C++ 模板类指针c++声明
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6342464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Template class pointer c++ declaration
提问by randomBananas
template <typename T>
class Node
{...};
int main
{
Node* ptr;
ptr = new Node<int>;
}
Will fail to compile I have to to declare the pointer as
将无法编译我必须将指针声明为
Node<int>* ptr;
Why do I have to specify the type when declaring a pointer I haven't created the class yet, why does the compiler have to know what type it will be pointing to. And is it not possible to create a generic pointer and decide afterwards what type I want to assign it.
为什么在声明尚未创建类的指针时必须指定类型,为什么编译器必须知道它将指向什么类型。并且是否不可能创建一个通用指针并随后决定我想要分配什么类型。
回答by progician
Templating resolves types at compile-time. When you assign the new Node<int>
object to it, the pointer must know at compile-time what type exactly it is.
模板在编译时解析类型。当您将新Node<int>
对象分配给它时,指针必须在编译时知道它到底是什么类型。
Node<int>
and Node<std::vector>
can be very different in the binaries (the binary layout of your object changes completely according the template parameter) so it doesn't make any sense to have an unresolved pointer type to a template.
Node<int>
并且Node<std::vector>
在二进制文件中可能有很大不同(对象的二进制布局完全根据模板参数改变),因此具有指向模板的未解析指针类型没有任何意义。
You should define first a common parent class for your nodes:
您应该首先为您的节点定义一个公共父类:
class NodeBase
{ ... }
template<typename ValueT>
class Node : public NodeBase
{
...
};
NodeBase* ptr;
回答by James Kanze
The simple answer is because C++ uses (fairly) strict static type
checking. Node<int>
is a completely unrelated type to Node<double>
,
and when the compiler sees ptr->doSomething()
, it has to know whether
to call Node<int>::doSomething()
or Node<double>::doSomething()
.
简单的答案是因为 C++ 使用(相当)严格的静态类型检查。 Node<int>
是与 完全无关的类型Node<double>
,当编译器看到时ptr->doSomething()
,它必须知道是否调用Node<int>::doSomething()
或Node<double>::doSomething()
。
If you do need some sort of dynamic generality, where the
actual type ptr
will point to will only be known at runtime, you need
to define a base class, and derive from that. (It's a fairly common
idiom for a class template to derive from a non-template base, precisely
so that the generality in the pointers can be resolved at runtime.)
如果您确实需要某种动态通用性,其中实际类型ptr
将指向将仅在运行时已知,您需要定义一个基类,并从中派生。(对于从非模板基派生的类模板来说,这是一个相当常见的习惯用法,正是为了可以在运行时解决指针中的通用性。)
回答by Tony Delroy
Why do I have to specify the type when declaring a pointer I haven't created the class yet, why does the compiler have to know what type it will be pointing to.
为什么在声明尚未创建类的指针时必须指定类型,为什么编译器必须知道它将指向什么类型。
There are lots of things you're allowed to do with a pointer, just to list a very few:
你可以用指针做很多事情,这里只列出几个:
- call one of many functions based on the pointer's type
- index from it (on the assumption that it points to the first elements in a contiguous array of such objects)
- take the size of the pointed-to object
- pass it to a template where the pointer-type is a parameter
- 根据指针的类型调用许多函数之一
- 来自它的索引(假设它指向此类对象的连续数组中的第一个元素)
- 获取指向对象的大小
- 将其传递给指针类型为参数的模板
For the compiler to generate code to do these efficiently, it needs to know the type of the pointer. If it defered the decisions until it saw the type of the pointer, then it would need to either:
为了让编译器生成代码以有效地执行这些操作,它需要知道指针的类型。如果它推迟决策直到它看到指针的类型,那么它需要:
- compile efficient code for every possible type the pointer might later take (making a hugely bloated program), or
- create inefficient code that can handle all the possible types through some worst-case pessimistic clumsy behaviours, or
- embed a copy of itself (the compiler) into your C++ program so it can complete it's job when it's got the necessary information - that would make every trivial program huge (and slow)
- 为指针以后可能采用的每种可能的类型编译有效的代码(制作一个非常臃肿的程序),或者
- 通过一些最坏的悲观笨拙的行为,创建可以处理所有可能类型的低效代码,或者
- 将自身(编译器)的副本嵌入到您的 C++ 程序中,以便在获得必要信息时完成它的工作 - 这将使每个琐碎的程序变得庞大(并且缓慢)
And is it not possible to create a generic pointer and decide afterwards what type I want to assign it.
并且是否不可能创建一个通用指针并随后决定我想要分配什么类型。
Kind of... you have many options:
有点……你有很多选择:
- use a
void*
, but before it can meaningfully operate on the pointed-to-type again you'll need to manually cast it back to that type: in your case that means recording somewhere what it was then having separate code for every possibility - use
boost::any<>
- pretty much like avoid*
, but with safety built in - use
boost::variant<>
- much safer and more convenient, but you have to list the possible pointed-to types when you create the pointer - use a runtime polymorphic family of objects and virtual dispatch... this is classic Object Oriented Programming... you have a pointer to an "abstract"
Node
that declares the shared functions and member data you'd use to operate on any particular type of node, then the templatedNode
class derives from that abstractNode
and implements type-specific versions of the functions. These are then called via a pointer to the base class usingvirtual
functions.
- 使用 a
void*
,但在它再次对指向类型进行有意义的操作之前,您需要手动将其转换回该类型:在您的情况下,这意味着在某处记录它然后为每种可能性使用单独的代码 - 使用
boost::any<>
- 非常像 avoid*
,但具有内置的安全性 - 使用
boost::variant<>
- 更安全,更方便,但您必须在创建指针时列出可能的指向类型 - 使用运行时多态对象家族和虚拟调度......这是经典的面向对象编程......你有一个指向“抽象”的指针,
Node
它声明了你用来操作任何特定类型的共享函数和成员数据node,然后模板化Node
类从该抽象派生Node
并实现函数的特定类型版本。然后使用virtual
函数通过指向基类的指针调用它们。
回答by David Hammen
As both Neil Butterworth and Luc Danton noted, you can't have a pointer of type Node* because Node is not a type. It is a template. Yes, Node is a class template, but that classhere just qualifies the kind of template. One way to look at it: Just as classes and instances of classes are very different things, so too are templates and template instantiations. It is those template instantiations such as Node that are classes. The class template is some other kind of beast.
正如 Neil Butterworth 和 Luc Danton 所指出的,您不能拥有 Node* 类型的指针,因为 Node 不是类型。它是一个模板。是的,Node 是一个类模板,但是这里的那个类只是限定了模板的种类。一种看待它的方式:正如类和类的实例是非常不同的东西一样,模板和模板实例化也是如此。正是像 Node 这样的模板实例化才是类。类模板是另一种野兽。
回答by David Hammen
Whenever you create any kind of object (including pointers) in C++, the full type of the object must be known. There is no such type in your code as Node
, so you can't create instances of pointers to it. You need to rethink how you are designing and writing your code.
每当您在 C++ 中创建任何类型的对象(包括指针)时,都必须知道该对象的完整类型。您的代码中没有像 那样的类型Node
,因此您无法创建指向它的指针实例。您需要重新考虑如何设计和编写代码。