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

Arjen Hiemstra ahiemstra at heimr.nl
Mon Jul 25 14:21:43 BST 2022


On Monday, 25 July 2022 14:22:45 CEST Friedrich W. H. Kossebau wrote:
> Am Montag, 25. Juli 2022, 10:19:39 CEST schrieb David Redondo:
> > Am Samstag, 23. Juli 2022, 17:20:08 CEST schrieb Friedrich W. H. Kossebau:
> > Adding such an overload as in your example is source incompatible
> > regardless. See also our guidelines.
> > https://community.kde.org/Policies/
> > Binary_Compatibility_Issues_With_C%2B%2B#Note_about_ABI
> > 
> > You cannot...
> > 
> >   For existing functions of any type:
> >     Add an overload (binary compatible, but not source compatible: it
> >     makes
> > 
> > &func ambiguous). Adding overloads to already overloaded functions is ok
> > (since any use of &func already needed a cast).
> 
> Indeed, this also was not on the radar of all those adding the overloads to
> KMessageBox recently, will discuss elsewhere.
> 
> But let's try to improve the example then, as the new challenge by {} still
> exists:
> 
> Given a class C with methods fpo() and foo(A a):
> --- 8< ---
>     class C
>     {
>     public:
>         void foo();
>         void foo(A a);
>     };
> --- 8< ---
> 
> Now you want to add an overload, to serve further use-cases as requested by
> API consumers:
> --- 8< ---
>         void foo(B b);
> --- 8< ---
> 
> 
> But there is existing consumer code, making use of C++17, which calls
> --- 8< ---
>     C c;
>     c.foo({});
> --- 8< ---
> 
> So the new overload will not be source-compatible and break existing code.
> 
> What to do about {} being a API addition roadblocker here in C++17 worlds?

You could try using SFINAE:

```
struct Test {
        void foo() { }
        void foo(const std::vector<int>& t) { }

        template <typename T>
        void foo(const T& t, std::enable_if_t<std::is_same<T, 
std::map<int,int>>::value, bool> = false)
        {
        }
};

Test t;
t.foo({});
```

In this case, the second overload will not be considered for `{}` as its type 
will be deduced as `std::initializer_list` and will not be the same as 
`std::map<int, int>`.

- Arjen

> 
> Cheers
> Friedrich






More information about the kde-devel mailing list