【问题标题】:Deduce a type from a void pointer从 void 指针推断类型
【发布时间】:2012-03-19 13:54:25
【问题描述】:

考虑以下示例:

class MyContainer {
    std::vector<void *> v;
public:
    void Put(void *x) { v.push_back(x);}
    void* Get(int index) { return v[index];}
};

void Work (MyContainer& c) {
    // cast_to_type(c.Get(0));
}

int main() {
    int x = 1;
    double y = 2.0;
    MyContainer c;
    c.Put(&x);
    c.Put(&y);

    Work(c);

    return 0;
}

假设函数Work 对向量指针指向的对象一无所知。还假设继承不是一种选择,并且指向对象的类型可以是任意的(可以有无限数量的类型)。

是否可以仅使用 MyContainer::Get 函数返回的 void 指针来推断类型?这可以使用强制转换、模板和typeid 运算符的任意组合来完成吗?

【问题讨论】:

  • 简答:否。
  • 如果我使用模板来包装对象,然后将指针指向被包装的对象呢?我可以使用模板以某种方式保存有关类型的信息吗?
  • @Diggy:不是直接的,但您现在可以通过这个包装器应用继承。见boost::any
  • @Diggy - 是的,但是你并没有真正使用void * 指针。 void * 暗示它实际上可以指向任何东西。无论如何,您使用的任何模板解决方案最终都会重新发明boost::any 或类似的东西。

标签: c++ void-pointers


【解决方案1】:

不,void*s 绝对没有与它们相关的任何信息,并且当您将指针投射到 void* 时,您会完全丢失类型。您必须找到另一种方法将不同类型存储在同一个容器中,例如使用继承。

你也可以这样做:

class MyContainer {
    struct cont {
        void* ptr;
        type_info* ti; // pointer, not reference, so this struct can be copied
    };

    std::vector<cont> v;

public:
    template<typename T>
    void Put(T* x) {
        v.push_back({ x, &typeid(T) });
    }

    // do whatever you want with Get using *v[x].ti
};

int x = 1;
double y = 2.0;
MyContainer c;
c.Put(&x);
c.Put(&y);

Work(c);

但是如果不知道您要做什么,我不知道这会有多大帮助。你可能不得不求助于更高级的东西,比如boost::any

【讨论】:

  • 你比我的编辑快:)。如果继承是不可能的怎么办。
  • 不幸的是,我不能使用 type_info 将我的 void 指针重新转换为正确的类型。见Typecasting_with_type_info。所以这仍然不能解决我的问题。
  • @Diggy 那么不幸的是没有解决方案; C++ 没有做你想做的事的工具(除了,正如我所说,使用类似boost::any 的东西)。或许你能告诉我们你想做什么?
  • 感谢赛斯的回答。 boost::any 也没有真正解决这个问题。它确实可以将不同的对象存储到单个容器中,即 std::vector,这很好。此外,它还支持将封装的对象转换为正确的类型,尽管您必须再次知道要调用转换方法的类型。这个问题似乎没有解决办法,所以即使你的回答有用,我也不能接受它作为一个确定的答案。
  • @Diggy 其实,虽然没有解决办法,但肯定有答案,就是“你做不到”,这就是我的回答。如果你告诉我你到底想做什么,我可能会提供更多帮助。
猜你喜欢
  • 2011-02-05
  • 1970-01-01
  • 2021-09-20
  • 2015-02-14
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多