Why C++ Is Terrifying
twitter.com
twitter.com
I'm not super familiar with C++'s memory model, especially since they have deprecated the notion of POD and replaced it with trivially constructable.
My rudimentary thought process is that you can't just "move" raw functions because there is probably some assumptions made that a C++ function's call-site isn't going to move around if it isn't owned by an object. Otherwise, the runtime would have to deduce the location of the function call every time.
Well, on second thought, is there any reason why an int function ptr should be any different from an int ptr?
Asking as someone who has been writing C++ on-and-off for a few years for games, school, etc. but never professionally.
I don't know any other example, but in Itanium, a function pointer is not just an address but an (address+address) pair where the second address is a sort of a base pointer for data segment:
so usually (but not always), sizeof(int ptr) == sizeof(func ptr)
checking std::is_trivially_copyable<FnPtrType>::value
using FnPtrType = int (*)(int) // for example
First of all there's std::function, which uses Type Erasure https://blog.the-pans.com/type-erasure/. It means std::function<void(int)> can be the type of anything callable that takes an int and returns void (lambda, function pointer, object with operator() overload, etc.). Notice they are of different types! Hence Type Erasure.
How std::function manages its memory is poorly specified. But the standard at least states that if it's initialized from a function pointer (free, no capture), it's guaranteed that it won't allocate. https://en.cppreference.com/w/cpp/utility/functional/functio...
> When the target is a function pointer or a std::reference_wrapper, small object optimization is guaranteed, that is, these targets are always directly stored inside the std::function object, no dynamic allocation takes place.
In this case, std::function is trivially copyable. However, there's no way to know this at compile time, exactly because the type is erased in std::function.
So basically duck typing?
* there will be only one instance of it;
* you'll be able to export such a function in public interface of a dynamic library without exposing its source code in a header file;
* compilation will be faster, because the compiler won't have to instantiate N different versions of a template;
* you'll see fewer scary template errors.
Your life as a human being will be happier.
Of course there are better alternatives to std::function in the wild, but the general idea remains.
std::invokable will just make working with templates nicer. But not working with templates is nicer still.
EDIT: You can think of std::function as the LSP inside C++. There is a famous matrix where rows are for editors, and columns are for languages. In case of std::function rows are functions accepting functions as arguments, and columns are functions passed as function arguments. The matrix represents template instantiations, when you use templates. By using std::function you avoid the matrix and instead have just two vectors of length N and M, if the matrix was NxM (N functions accepting functions as arguments, M functions passed as arguments).