Provide complete implementation of std::function
, std::function_ref
, and std::move_only_function
equivalent to those in the C++26 <functional>
header.
- Macro-free implementation
- The size of each specialization is two pointers
- Not require RTTI
- Support classes without
operator()
The implementation does not guarantee the best performance under all use cases but provides adequate code size & quality while maintaining full conformance.1
Toolset | Standard Library | Test Environment |
---|---|---|
GCC >= 11.1.0 | libstdc++ | Ubuntu 20.04 |
MSVC >= 14.30 | Microsoft STL | Visual Studio 2022 |
Clang >= 17.0.6 | libc++ | Xcode 16.0 |
It's a header-only library. You may also install and consume its CMake targets:
find_package(nontype_functional CONFIG REQUIRED)
target_link_libraries("main" PRIVATE std23::nontype_functional)
#include <std23/function_ref.h>
using std23::function_ref;
void parse_ini(function_ref<size_t(char *, size_t)> read_cb);
...
#include <stdio.h>
int main()
{
auto fp = ::fopen("my.ini", "r");
parse_ini([fp](auto ptr, auto n)
{ return ::fread(ptr, 1, n, fp); });
::fclose(fp);
}
Ignore the fact that the code has no error handling or resource-safety; the callable wrappers, function_ref
in the example, generalized the idea of callbacks. You can pass anything with a matching call pattern to another function, parse_ini
in here, without turning the latter into a template.
Now, what if you have an existing class that can read data, but it's not a function object?
class data_source
{
...
public:
auto read(char *, size_t) -> size_t;
};
Then you may designate a named member function, read
in this example, to serve the role of an operator()
:
using std23::nontype;
int main()
{
data_source input;
parse_ini({nontype<&data_source::read>, input});
}
The nontype
tag generalized the idea of delegates from other languages, like C♯. What replaces operator()
doesn't have to be a member function. You can also use a free function or even a lambda:
int main()
{
auto fp = ::fopen("my.ini", "r");
parse_ini({nontype<[](FILE *fh, auto ptr, auto n)
{ return ::fread(ptr, 1, n, fh); }>,
fp});
::fclose(fp);
}
Feels like creating a member function for FILE
on the fly, isn't it?
- 0.8 –
std::function_ref
&std::function
- 0.9 –
std::move_only_function
- 1.0 –
nontype_t
constructors formove_only_function
- 1.1 –
copyable_function
from P2548 - 1.2 – Support C++20 modules
cppreference page for std::function
cppreference page for std::move_only_function
cppreference page for std::function_ref
Footnotes
-
Except for
std::function
'starget()
member function, which is unimplemented because it requires RTTI. ↩