Вывести тип из пустого указателя - PullRequest
3 голосов
/ 01 марта 2012

Рассмотрим следующий пример:

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 ничего не знает об объектах, на которые указывают векторные указатели. Также предположим, что наследование не является опцией и что типы указанных объектов могут быть произвольными (может быть бесконечное количество типов).

Можно ли вывести тип, используя только указатель void, возвращаемый функцией MyContainer::Get? Можно ли это сделать, используя любую комбинацию приведений, шаблонов и оператора typeid?

1 Ответ

9 голосов
/ 01 марта 2012

Нет, 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...