Home > OS >  Declare a template pointer without knowing the type
Declare a template pointer without knowing the type

Time:11-11

I have this code with a template function. The function can accept any object that is inherited from Object or with an operator providing a pointer to an Object instance. Inside the function I need to get the Object pointer, but it is a template type and I can't figure out the way how to specify the template type.

here is the code:

class IObject
{
};

template<class T>
class Object: public IObject
{
    typedef T value_type;
public:
    void test()
    {
    }
    operator Object<T>*()
    {
        return this;
    }
};

template<class T>
class Wrapper
{
    typedef T value_type;
public:
    T object;
    operator T*()
    {
        return &object;
    }
};


template<class T>
class Container
{
public:
    void func()
    {
        data.resize(1);
        typename T::value_type& ref = data[0];
        //IObject* object = ref; //works
        Object<?>* object = ref; // How can I specify the template type here?
        object->test();
    };
    T data;
};

int main()
{       
    Container<std::vector<Object<float>>> container1;
    container1.func();
    Container<std::vector<Wrapper<Object<int>>>> container2;
    container2.func();

    return 0;
}

I tried playing with value_type, but as there are technically 2 types of objects can be used as an input, it doesn't work. Also I tried adding extra argument to the function template, but the argument type can't be deduced by the compiler.

CodePudding user response:

First off, either your Wrapper is wrong or your usage of it is wrong. You instantiate Wrapper<Object<int>> but in the class you have:

Object<T> object;
operator Object<T>*()

which is instantiated as

Object<Object<int>> object;
operator Object<Object<int>>*()

You should either instantiate Wrapper<int>, which would "wrap" a Object<int>, or change your class to have this instead:

T object;
operator T*()

but then the typedef T value_type is wrong.

In any case, you can create a type trait to "unwrap" the type:

template<class T>
struct UnwrapT {
    using type = T;
};

template<class T>
struct UnwrapT<Wrapper<T>> {
    using type = Object<T>;
};

template<class T>
using Unwrap = typename UnwrapT<T>::type;

You can then use this in func:

Unwrap<typename T::value_type>* object = ref;

Demo

  • Related