Challenge: adding new method overloads when existing consumers use {} with args

Friedrich W. H. Kossebau kossebau at kde.org
Mon Aug 15 17:44:32 BST 2022


Am Donnerstag, 28. Juli 2022, 14:38:38 CEST schrieb Friedrich W. H. Kossebau:
> Am Donnerstag, 28. Juli 2022, 01:50:28 CEST schrieb Thiago Macieira:
> > But {} is particularly special, so I don't know how we'd deal with it. I
> > don't think this has come up for us yet. For one, the mailing list thread
> > linked in the QUIP didn't address it.
> 
> Not subscribed there these days, will try to read up on the ML archive, but
> also happy if you could relay any new info here :)

Had a look into the Qt ML archives, and by the two replies listed 
there seems that so far people simply accept that the consumer using "{}" 
prevents further overloads, and also they would not know about any tricks to 
deal with that:

https://lists.qt-project.org/pipermail/development/2022-July/042813.html
https://lists.qt-project.org/pipermail/development/2022-August/042842.html

Then had also asked via a blog post for ideas:

https://frinring.wordpress.com/2022/08/06/c17s-impeding-sc-for-new-method-overloads/

And there people came up with the solution to catch the expression "{}" by 
using a method taking a std::initializer_list for some dummy type, which 
seemed to work on initial testing, the compiler did not proceed to consider 
the value-initialization of any type while trying to resolve the expression 
when there was the std::initializer_list type available as parameter type:
--- 8< ---
    struct Dummy { Dummy() = delete; };
    [[deprecated("Use explicit type A with argument please")]]
    void foo(std::initializer_list<Dummy>) ( /*forward*/ foo(A()); )
--- 8< ---

So this might be a working approach to the very problem given as challenge.

But... the related discussions brought up more pitfalls:

When existing calls uses non-empty curly braces to construct an object on the 
fly, that needs yet another approach yet to be found, to have 
the compiler decide itself for a dedicated method with deprecation warnings. 

And then a shower thought popped up hinting that things are even spoiled 
without C++17 and {} expressions, due to all implicit conversions possible 
since ages e.g. by type operators:

Given a class X in 3rd-party code which can be converted both to A & B:
--- 8< ---
    class X
    {
    public:
        operator A() const { return A(); }
        operator B() const { return B(); }
    };
--- 8< ---
And elsewhere the code happily relies on the conversion e.g. when calling 
C::foo(A):
--- 8< ---
    C c;
    c.foo(somethingReturningX());
--- 8< ---

So us adding the new overload to class C
--- 8< ---
        void foo(B b);
--- 8< ---
would make things ambiguous to the compiler -> unhappy consumer. Actually 
Thiago before pointed to a similar issue with implicit conversions from 
character literal with Qt types, but I failed to see the principle.

So the new overload needs to be taken out of the first round of candidate 
finding, e.g. by using the trick Thiago pointed out being done in Qt6, making 
the method a template by adding some dummy "template <typename = void>", to 
achieve both BC & SC for the current release series.

Just we fail to catch consumer calls then and trigger warnings about the 
upcoming SC breakage on the next BC breakage, when the overloads are to be 
cleaned up from all the compatibilty helper methods again. But seems it is 
simply all we can do here.

Thanks for the input everyone so far. Myself putting this issue aside for now 
(and also not adding notes to the KDE Compat page), have to delay continuing 
once I run into the next real world case.
Happy to have someone pick up in the meantime if someone has interest.

Cheers
Friedrich




More information about the kde-devel mailing list