4

I have got several classes which are derived from QWidget Also I have template function like this

    template<typename T>
    QWidget* create(){return static_cast<QWidget*>(new T());}

now I want to create container:

    QMap<int, className> classes // it is not compiling 

so, that I can use the container values as function template type:

    QWidget* widget = create<classes[i]>();

How should I do it?

lnk
  • 593
  • 2
  • 11
  • 27

2 Answers2

2

Classes are not first-class objects in C++ (i.e. they're not data that can be passed around or stored in containers). There is something that rensembles the class "name", but indeed you've no guarantee that it's a readable name and you cannot create an instance given the name anyway.

What you can do instead is making a map from int to function pointers because those are first-class objects:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "derivedwidget.h"
#include <QMap>

template<typename T>
QWidget *create() { return new T; }

QMap<int, QWidget *(*)()> wmap;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    wmap[1] = &::create<DerivedWidget>;

    this->setCentralWidget(wmap[1]());
}

MainWindow::~MainWindow()
{
    delete ui;
}
6502
  • 112,025
  • 15
  • 165
  • 265
  • I tried to compile your answer. Compiler gives me an error: **no matches converting function 'create' to type 'class QWidget* (*)()' in creators[1]=&create;** – lnk Feb 13 '15 at 18:35
  • @lnk: the code shown above compiles and works fine. One problem I had is that name `create` is problematic when inside a widget because it's a name already defined by Qt. Using the `::` prefix solved this issue. – 6502 Feb 13 '15 at 19:42
0

The template approach won't work unless the type of the widget is known at compile time. If you want to make it work, knowing what sort of widget you want at runtime, you can have a function that creates the right type of widget, given a string:

QWidget* Create(const string& widgetType)

Now, to make this work you need a mechanism to automatically map classes (derived from QWidget in your case) to strings. This thread should be helpful in how to do this.

Community
  • 1
  • 1
opetroch
  • 3,929
  • 2
  • 22
  • 24