Overloading: The Bane of All Higher-Order Functions - Simon Brand [ CppCon 2018 ]

preview_player
Показать описание


Support for functional programming has been consistently growing in C++. Lambdas, new algorithms, variant visitation and std::apply are just a few of the many additions which make use of the paradigm more natural, expressive and powerful. Unfortunately, passing overloaded functions or function templates to higher-order functions is not as simple as it sounds, which forces users to adopt various unsatisfactory workarounds. This talk will discuss a few solutions, show how C++ still has a way to go in providing language support, and examine some existing standards proposals which could help.

Techniques discussed will include wrapping up overload sets in lambdas; maintaining noexcept specifications, return types, and brevity; global function objects; and avoiding subtle One Definition Rule (ODR) violations.

Simon Brand, Microsoft
C++ Developer Advocate

Simon is a C++ Developer Advocate at Microsoft. He turns into a metaprogramming fiend every full moon, when he can be found bringing compilers to their knees with template errors and debating undefined behaviour online. He co-organises the Edinburgh C++ user group and contributes to various programming standards bodies.

Outside of programming, he enjoys experimental films, homebrewing, and board games.



*-----*
*-----*
Рекомендации по теме
Комментарии
Автор

Good talk! I strongly agree that this is *not* just an issue for library authors. Especially with ranges coming, it would be very useful to have a cleaner, more succinct way to pass operators to algorithms. Something like the solutions discussed at the end would be a huge win for doing functional programming in C++.

JonathanSharman
Автор

Good talk Simon. However I was expecting to see older proposals solving this issue and why the committee rejected them.

I've my own reasons, but It is not clear from the presentation why do you find good f([]foo) and not f(foo{})?

I understand that foo without more qualifications could represents an overload set in some future language, however, today it is not an object that represents the overload set, it is either a pointer to the function if there is only one or ambiguous if there are more overloads.

I agree that we could do the implicit conversion from a symbol foo to his overload set when we are expecting an overload set. However having to add in the language functions that expect an overload set is something weird to me. The function is expecting a function that takes some specific parameters not an overload set.

I want to state this clearly at the interface level, and I cannot without paying more that I'm ready to do.
As we are dreaming today, I would like to be able to express that my algorithm f can take any function taking an int and returning an int.

void f( ((int) -> int) fct);

When I use
int foo(int); // (1)
int foo(std::string); // (1)

f(foo);

I would expect that the compiler will use the overload of foo that respects the constraint of f.

(int) -> int

would be a short hand for a template

template <Callable<int(int)> F>
void f(F&& fct);

The question is how to define a function taking a function that takes either an int or an std::string and returns an int

void f( ( (int) -> int |  (std::string) -> int) fct);

Here we could take advantage of an implicit conversion of foo to this kind of types.

I don't understand what overload_set<F> is.


Just my 2 cts

botetescribavicentej.
Автор

More than 5 years later, nothing has been fixed :(

lorenzobolis
Автор

The special deduction rule makes overload_set unusable for std::function, function_ref etc.

YourCRTube
Автор

the person who asked Simon Brand has deragatory tones while Simon puts his opinon regarding the overload_set though

shahmiBro