在 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 typeidoperator 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 strvariable 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 不存储类型;它是类型的别名。

