Click here to Skip to main content
15,886,518 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am wondering how to accomplish this.

C++
template <class T>
class dynamic
{
    friend myclass;
    T dyn_data;
    dynamic() : dyn_data(0) { }
    dynamic(T Data) : dyn_data(Data) { }
}

class myclass
{
private:
    void * m_data;
public:
    myclass() : m_data(nullptr) { }
    ~myclass() { if (m_data != nullptr) delete m_data; }
    template <typename Type> myclass(Type data) { SetData<Type>(data); }
    template <typename Type> void SetData(Type data)
    {
        m_data = new dynamic<Type>(data);
    }
    template <typename Type> void GetData() const
    {
        dynamic<Type> * data;
        data = static_cast <dynamic<Type>*> (m_data);
        return (Type) data->dyn_data;
    }
}

int main()
{
    //This code works as designed
    myclass data1;
    data1.SetData<int>(12);
    int x = data1.GetData<int>();

    //This code also works but defaults the type to a double
    myclass data2(123.4);
    float y = data2.GetData<float>();

    //But intellisense flags this for errors
    myclass<float> data3(234.5);  //class 'myclass' cannot have a template argument list
    float z = data3.GetData<float>(); // multiple errors on this line

    //This is also flagged as an error
    myclass * data4 = new myclass<float>(345.6);
}


In a nutshell, I am trying to pass templated types into a class constructor so that an internal templated class can be constructed.
It was possible by creating the class with the default constructor and populating the data through a template function.
Internet searches for "template" and "constructor" return nothing but links to implementing template classes.

I guess my question is, is it possible to pass template arguments in a class constructor?
I've tried multiple configurations of the line that has the error but I cannot find one that works.

If it is, what am I doing wrong.
If not, well it's an interesting idea.
Posted

1 solution

You can not pass template arguments but the compiler can automatically find out the types for you. You have to explicitly typecast the ctor arguments in some cases to specify the exact types.

There you go, here is a working bugfixed example:
C++
class base_data
{
public:
    // This virtual "method" will make sure that the base class has a vtable and in turn, RTTI typeinfo.
    // We need the virtual destructor here anyway because we destruct the data using a pointer to the base class...
    // Deleting a base class pointer when the base class doesn't have a virtual destructor is always a BUG.
    virtual ~base_data() {}
};

template <class T>
class dynamic : public base_data
{
    friend class myclass;
    T dyn_data;
    dynamic() : dyn_data(0) { }
    dynamic(T Data) : dyn_data(Data) { }
};

class myclass
{
private:
    base_data* m_data;
public:
    ~myclass()
    {
        delete m_data;
    }
    myclass() : m_data(nullptr) {}

    template <typename Type>
    myclass(Type data)
    {
        m_data = new dynamic<Type>(data);
    }

    template <typename Type>
    void SetData(Type data)
    {
        delete m_data;
        m_data = new dynamic<Type>(data);
    }

    // This seems to be a useless method in this form...
    template <typename Type>
    Type GetData() const
    {
        dynamic<Type> * data;
        // slow, but it doesn't crash at least...
        data = dynamic_cast<dynamic<Type>*>(m_data);
        return data ? data->dyn_data : Type();
    }
};

void test()
{
    //This code works as designed
    myclass data1;
    data1.SetData<int>(12);
    // the compiler finds out that Type is int
    data1.SetData(12);
    int x = data1.GetData<int>();

    // the compiler finds out that Type is float
    myclass data2(123.4f);
    float y = data2.GetData<float>();

    myclass data3(234.5f);
    float z = data3.GetData<float>();

    // the compiler finds out that Type is double
    myclass * data4 = new myclass(345.6);
    delete data4;
}
 
Share this answer
 
Comments
Foothill 26-Jan-14 17:03pm    
Wow. It never occurred to me to use polymorphism to get past the compile time type checking.
CPallini 26-Jan-14 17:19pm    
My 5. I was plainly wrong.
pasztorpisti 26-Jan-14 17:27pm    
Thank you!
Foothill 26-Jan-14 17:38pm    
What if I want to use run-time type checking to dynamically create my data classes?
pasztorpisti 26-Jan-14 17:43pm    
Why would you do runtime type checking when you can do compile time check that is much better? There are cases where the only possible way to go is runtime type checking of course but that is rare and can be avoided in most of the time. I use dynamic type checking usually when performance isn't critical and I can save time by writing code that does runtime type checking to save myself time by not designing/writing the code that does the same without runtime type checking. I do this usually in experimental research (throw-out) code only. In a lot of cases runtime type checking can be avoided using design patterns (for example visitor pattern) but you need even this one rarely.

Runtime type checking the incoming data to create other dynamically handled objects... Sounds like a double-wrong solution...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900