> On 5 Nov 2025, at 09:32, André Somers via Development 
> <[email protected]> wrote:
> 
> 
> On 05-11-2025 09:10, Arno Rehn wrote:
>> On 05.11.2025 08:22, Daniel Schürmann wrote:
>>> However I am not confident that this bullet proved enough for being 
>>> integrated in the upstream library.
>>> * It works by guessing the parent argument which can fail at runtime 
>>> without even a compiler message, in users code.
>>> * It does not yet (<x++23) support constructors requiring a sub class 
>>> parent like QWidget or any other user defined sub class.
>>> * We can make it more robust by constructing without parent and then call 
>>> setParent() causing some extra calls and bookkeeping. I don't want that.
>> 
>> Honestly I think you're over-engineering this somewhat. "parent comes last" 
>> is an established convention when dealing with QObject-derived classes. 
>> QWidgets are the same, see for example QPushButton:
>> 
>>     QPushButton(const QIcon &icon, const QString &text, QWidget *parent)
>> 
>> Just forward the args and append "this" as the last parameter to pass the 
>> parent along.
> 
> Problem is, I guess, that while it is a convention, it is not true 100% of 
> the time. Not even in Qt. See QWidget for instance as a counterexample:
> 
>     [explicit] QWidget::QWidget(QWidget *parent = nullptr, Qt::WindowFlags f 
> = Qt::WindowFlags())
> 
> For customer code, you can't be sure people followed this convention at all 
> of course.
> 
>> 
>> Re subclass parents: You don't actually need C++23 for that. We can (ab-)use 
>> a templated implicit conversion operator to auto-cast a type to the one 
>> required by the constructor:
> 
> Wow... that looks... dirty. My kind of dirty trick.
> 
> Cheers,
> 
> André


Even QWidget can be created with the parent pointer as the last argument, as 
the flags argument is optional.

The limitation here is rather that createChild<QWidget> cannot be used to 
create a child widget with window flags. That’s acceptable - the flags can be 
set after the fact as well.

Not being able to create types that have no suitable constructor is an 
acceptable, documentable, and static_assert’able limitation. We could even fall 
back to an explicit “newChild->setParent(this)” call after constructing the 
child type without parent argument.

And again, we need to make sure that object->createChild<QWidget>() is not 
possible; from what I see, that can be solved via SFINAE:

class QObject …
{
    template <typename ChildType, typename ...Args,
              std::enable_if_t<!std::is_base_of_v<QWidget, ChildType>, bool> = 
true
             >
    ChildType *makeChild(Args &&...args)
    {
        return new ChildType(std::forward<Args>(args)..., this);
    }
};

(it’s enough for QWidget to be forward declared, which it is already in 
qobject.h)

and then overloading this in QWidget without the constraint (a QObject can be a 
child of a QWidget).

Volker

-- 
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development

Reply via email to