Am Montag, 25. Juli 2022, 15:21:43 CEST schrieb Arjen Hiemstra: > 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>`.
Thanks, interesting idea. Drawbacks I see: * new overload method (and any further ones) will stay special * unless implementation is fine to do as part of template, needs another method * existing consumer code using {} is not that simple to map by human readers as to which overload will be used This inspires another idea though (still need to investigate if that works): there could be another template overload added which catches any `std::initializer_list` arg and delegating to the old method, thus removing the ambiguity and also allowing to emit a compiler warning for this usage? Cheers Friedrich