在 C++ 中存储类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2562176/
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
Storing a type in C++
提问by perimosocordiae
Is it possible to store a type name as a C++ variable? For example, like this:
是否可以将类型名称存储为 C++ 变量?例如,像这样:
type my_type = int; // or string, or Foo, or any other type
void* data = ...;
my_type* a = (my_type*) data;
I know that 99.9% of the time there's a better way to do what you want without resorting to casting void pointers, but I'm curious if C++ allows this sort of thing.
我知道 99.9% 的时间有更好的方法来做你想做的事,而不必求助于强制转换空指针,但我很好奇 C++ 是否允许这种事情。
采纳答案by Thomas
No, this is not possible in C++.
不,这在 C++ 中是不可能的。
The RTTI typeid
operator allows you to get some information about types at runtime: you can get the type's name and check whether it is equal to another type, but that's about it.
RTTItypeid
运算符允许您在运行时获取有关类型的一些信息:您可以获取类型的名称并检查它是否等于另一个类型,但仅此而已。
回答by Michael Aaron Safyan
Not as written, but you could do something similar...
不像写的那样,但你可以做类似的事情......
class Type
{
public:
virtual ~Type(){}
virtual void* allocate()const=0;
virtual void* cast(void* obj)const=0;
};
template<typename T> class TypeImpl : public Type
{
public:
virtual void* allocate()const{ return new T; }
virtual void* cast(void* obj)const{ return static_cast<T*>(obj); }
};
// ...
Type* type = new TypeImpl<int>;
void* myint = type->allocate();
// ...
This kind of thing can be extended depending on what features you need.
这种事情可以根据您需要的功能进行扩展。
回答by Chris H
You can't do that in C++, but you can use the boost any library then test for the type it holds. Example:
你不能在 C++ 中做到这一点,但你可以使用 boost any 库然后测试它所拥有的类型。例子:
bool is_int(const boost::any & operand)
{
return operand.type() == typeid(int);
}
回答by Brian R. Bondy
No you can't store the type directly as you want, but you can instead store the name of the type.
不,您不能根据需要直接存储类型,但您可以存储类型的名称。
const char* str = typeid(int).name();
I guess whenever you planned to use that variable for comparison, you could instead at that time compare the str
variable against the name()
of the types.
我想每当您计划使用该变量进行比较时,您都可以在那个时候将str
变量与name()
类型进行比较。
const char* myType = typeid(int).name();
//....
//Some time later:
if(!strcmp(myType, typeid(int).name()))
{
//Do something
}
回答by wheaties
Yes, if you code it yourself.
是的,如果你自己编码。
enum Foo_Type{
AFOO,
B_AFOO,
C_AFOO,
RUN
};
struct MyFoo{
Foo_Type m_type;
Boost::shared_ptr<Foo> m_foo;
}
as commented below, what I left out was that all these "foo" types would have to be related to Foo. Foo would, in essence, be your interface.
正如下面所评论的,我遗漏的是所有这些“foo”类型都必须与 Foo 相关。本质上,Foo 将成为您的界面。
回答by David
Today I had a similar problem while coding:
I had the need to store a polymoriphic data type (here named refobj) over wich call functions of the concrete classes implementing it. I need a solution that doesn't cast the variable explicitly because I need to reduce the amount of code.
今天我在编码时遇到了类似的问题:
我需要在实现它的具体类的调用函数上存储一个多态数据类型(这里称为 refobj)。我需要一个不显式转换变量的解决方案,因为我需要减少代码量。
My solution (but I haven't tested it yet) looks similar to a previous answer. Actually is quite an experimental solution. It look like this...
我的解决方案(但我还没有测试过)看起来与之前的答案相似。实际上是一个相当实验性的解决方案。它看起来像这样...
// interface to use in the function
class Type
{
public:
virtual void* getObj()const=0;
};
// here the static_cast with the "stored" type
template<typename T> class TypeImpl : public Type
{
public:
TypeImpl(T *obj) {myobj=obj;}
virtual void* getObj()const{ return static_cast<T*>(myobj); }
private:
T* myobj;
};
// here the type that will contain the polimorific type
// that I don't want to cast explicitly in my code
Type *refobj;
// here the "user code "
void userofTypes()
{
( refobj->getObj() ).c_str();
// getObj() should return a string type over which
// calling string concrete functions ...let's try!
}
void main()
{
refobj=new TypeImpl < string > ( new string("hello") );
userofTypes();
}
// it might seem absurd don't cast refobj explicitly, but of
// course there are situation in which it can be useful!
回答by Thomas Matthews
A better process is to have a common base class containing a load method, and an interface for loaders. This would allow other parts of the program to load data generically without knowledge of the descendant class:
一个更好的过程是拥有一个包含 load 方法的公共基类和一个loader接口。这将允许程序的其他部分在不了解后代类的情况下一般加载数据:
struct Load_Interface;
struct Loader
{
virtual void visit(Load_Interface&) = 0;
}
struct Load_Interface
{
virtual void accept_loader(Loader& l)
{
l.visit(*this);
}
};
This design avoids the need to know the types of objects.
这种设计避免了了解对象类型的需要。
回答by Andres Jaan Tack
Types are not objects in C++ (where they are in Ruby, for instance), so you cannot store instances of a type. Actually, types never appear in the executing code (RTTI is just extra storage).
类型不是 C++ 中的对象(例如,它们在 Ruby 中),因此您无法存储类型的实例。实际上,类型永远不会出现在执行代码中(RTTI 只是额外的存储空间)。
Based on your example, it looks like you're looking for typedefs.
根据您的示例,您似乎正在寻找 typedef。
typedef int Number;
Number one = 1;
Number* best = (Number*) one;
Note that a typedef isn't storingthe type; it is aliasingthe type.
请注意,typedef 不存储类型;它是类型的别名。