0

I have base class and a bunch of derived classes (only one here for simplicity). I also have holder class with one of derived classes as a template argument. I want holder object to create an instance of derived class. Here is the code:

class base {
protected:
    int value;
public:
    base() : value (0) { }
    base(int value) : value(value) { }
};

class derived : public base { };

template <class T>
class holder {
public:
    holder(T) {}
    T create(int value) {
        return T(value);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    holder<base*> h(&derived());
    derived* d = h.create(1); // error here
}

I get an error error C2440: 'initializing' : cannot convert from 'base *' to 'derived *'. I guess that's because type of variable is holder<base*>, so create method is called with base as template argument. But how do I cast it properly if I have a lot of derived classes?

UPD. I changed holder::create method so it uses std::remove_pointer but I still get the same compile error.

T create(int value) {
    return new (std::remove_pointer<T>::type)(value);
}
11
  • Are you aware that you are creating a base* with an int ? Does your code compile ? Commented May 22, 2016 at 10:56
  • What are you trying to do? Didn't the compiler also issue an error about taking an address of a temporary? Commented May 22, 2016 at 10:57
  • Can the holder hold derived type rather than base type? Commented May 22, 2016 at 10:59
  • @SlardarZhang I also need to store a list of holder's, each may hold different subclasses of base (I should have mentioned it in post). So (as far as I understand c++) , no - it can only be holder<base*> Commented May 22, 2016 at 11:03
  • @perencia I see now, but don't understand what can I do with it. Commented May 22, 2016 at 11:11

1 Answer 1

1

You can let holder holds derived type rather than base type, and use boost::any or std::any (c++ 17) to store all the holders.

#include "iostream"
#include "boost/any.hpp"
#include "vector"

class base {
protected:
    int value;
public:
    base() : value (0) { }
    base(int value) : value(value) { }
};

class derived1 : public base {
public:
    derived1(int value) : base(value) {};
};
class derived2 : public base {
public:
    derived2(int value) : base(value) {};
};

template <class T>
class holder {
public:
    holder() {}
    T* create(int value) {
        return new T(value);
    }
};

int main()
{
    std::vector<boost::any> list;
    holder<derived1> h1;
    holder<derived2> h2;
    list.push_back(h1);
    list.push_back(h2);
    derived1* pd1 = boost::any_cast<holder<derived1>>(list[0]).create(1);
    derived2* pd2 = boost::any_cast<holder<derived2>>(list[1]).create(2);
}
Sign up to request clarification or add additional context in comments.

2 Comments

That seams to do what I need. Do you by any chance know is there any class for Qt?
I didn't heard that.@VladShevchenko

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.