1

I am trying to build a function that takes a (qt) Type as a parameter and uses it to find children. My function looks like this:

template <typename QType>
void MyClass::activateElements(QWidget *widget, QType t)
{
    QList<QType *> buttons = widget->findChildren(t);
    foreach( QType *button, buttons )
    {
        buttons->setEnabled(true);
    }
}

I have also tried

template <typename QType>
void MyClass::activateElements(QWidget *widget, QType)
{
    QList<QType *> buttons = (* widget).findChildren<QType *>();
    foreach( QType *button, buttons )
    {
        button->setEnabled(true);
    }
}

I instantiate an object of the class that uses this function in another class. There I try to use it like this:

    QDoubleSpinBox x;
    object_of_my_class->activateElements(correctWidget, x);

At this point I get stuck because I get the following error:

error: ‘QDoubleSpinBox::QDoubleSpinBox(const QDoubleSpinBox&)’ is private Q_DISABLE_COPY(QDoubleSpinBox)

How would I handle this problem, that QDoubleSpinBox and others are private? Have I approached how to build the function wrong or am I just using it incorrectly? Is there even a way to do it?

Shin
  • 678
  • 3
  • 12
  • 22
  • "_How would I handle this problem, that QDoubleSpinBox and others are private?_" The error states that **copy-constructor** of `QDoubleSpinBox` is private (i.e. it can't be copied). Pass by reference instead of passing by value. – Algirdas Preidžius Dec 29 '17 at 13:36

1 Answers1

2

It looks like you don't need an object of the type at all, only the type itself. In such case, specifying the template argument would be the way to go:

template <typename QType>
void MyClass::activateElements(QWidget *widget)
{
    QList<QType *> buttons = (* widget).findChildren<QType *>();
    foreach( QType *button, buttons )
    {
        button->setEnabled(true);
    }
}

// Usage:
object_of_my_class->activateElements<QDoubleSpinBox>(correctWidget);

This is how I would do it, as it expresses intent quite well.

If, however, you really want to enable type deduction from an existing object, pass it by reference to avoid the (forbidden) copy:

template <typename QType>
void MyClass::activateElements(QWidget *widget, const QType &)
{
    QList<QType *> buttons = (* widget).findChildren<QType *>();
    foreach( QType *button, buttons )
    {
        button->setEnabled(true);
    }
}

// Usage:
QDoubleSpinBox x;
object_of_my_class->activateElements(correctWidget, x);
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • Thanks a lot already! The first approach indeed seems to be the better option. I was there earlier but must have messed up the function call and then got lost. Using that again I get "undefined reference to `void MyClass::activateElements(QWidget*)`. I have defined it as `template void activateElements(QWidget *widget);` in the header file. Is this my mistake? – Shin Dec 29 '17 at 13:56
  • @Shin Have you *defined* it there (including the body), or just *declared* it there (and put its implementation into a `.cpp` file)? Only the former can work: see [Why can templates only be implemented in the header file?](https://stackoverflow.com/q/495021/1782465). – Angew is no longer proud of SO Dec 29 '17 at 14:00
  • I didn't know that function had to be defined in the `header` fie too. Did that and it is finally all working now. Thank you a lot for your help :) – Shin Dec 29 '17 at 14:16
  • @Shin Just to be crystal clear: *functions* don't have to, *function templates* do. – Angew is no longer proud of SO Dec 29 '17 at 14:33