How do I get the template type of a given element at runtime in C++?

前端 未结 3 947
情话喂你
情话喂你 2021-01-18 13:26

I\'m designing a simple Array class with the capability of holding any type of object, like a vector that can hold multiple types of data in one object. (This i

相关标签:
3条回答
  • 2021-01-18 13:59

    The return type of a function like Array::get_element must be determined at compile time. Since class Array does not know what types of containers it stores at compile time, the only option is to just return the base Container* pointer. Then users of that code can use virtual functions and/or dynamic_cast to deal with those generalized containers.

    0 讨论(0)
  • 2021-01-18 14:06

    I was thinking something along the lines of this template for your get_element.

    template <class T>
    T& Array::get_element(int i, T &t)
    {
        Object<T> *o = dynamic_cast<Object<T> *>(vec[i]);
        if (o == 0) throw std::invalid_argument;
        return t = o->object;
    }
    
    Array arr;
    double f;
    int c;
    
    arr.get_element(0, f);
    arr.get_element(1, c);
    

    But alternatively, you could use this:

    template <class T>
    T& Array::get_element(int i)
    {
        Object<T> *o = dynamic_cast<Object<T> *>(vec[i]);
        if (o == 0) throw std::invalid_argument;
        return o->object;
    }
    
    f = arr.get_element<double>(0);
    c = arr.get_element<int>(1);
    
    0 讨论(0)
  • 2021-01-18 14:12

    dynamic_cast<>(), when used on a pointer, can be used to check whether the cast is actually possible since it returns NULL when the types don't match.

    However, you'll probably want to reconsider your setup; dynamic_cast isn't something you'll want to use if you can avoid it, and having cascades of "if object-is-type1 then do this; else if object-is-type2 then do that; else if object-is-type3..." is almost always a sure sign of bad design.

    Using auto in your get_element is probably your trick of getting around the problem that you don't know what the type will be -- that won't work, though. The compiler still has to know the return type; it cannot change at runtime.

    EDIT: you might also go a step back and ask yourself whether you REALLY need an array that can store "anything". I've used Objective-C for a long time, and it's basically built around the idea that everything is just an "object" and people can call anything on anything, it's all sorted out at runtime. However, I found that actual uses of this are rare... and for containers in particular, I find that every NSArray that I use only has objects of one type, or maybe of a common base class, but not actually distinct, unrelated classes.

    0 讨论(0)
提交回复
热议问题