在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:55:21  来源:igfitidea点击:

Storing a type in C++

c++castingtypes

提问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);
}

http://www.boost.org/doc/libs/1_42_0/doc/html/any/s02.html

http://www.boost.org/doc/libs/1_42_0/doc/html/any/s02.html

回答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
}

More info available here

此处提供更多信息

回答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 不存储类型;它是类型的别名