Generic function-wrapper object

39 views
Skip to first unread message

Hamza Sood

unread,
Apr 9, 2018, 11:36:14 AM4/9/18
to ISO C++ Standard - Future Proposals
I propose the inclusion of a function object (somewhat similar to the deprecated ptr_fun) that looks something like:

template<auto f>
requires is_pointer_v
<decltype(f)> &&
         is_function_v
<remove_pointer_t<decltype(f)>>
struct func_ptr {
 
template<typename... Args>
 
decltype(auto) operator()(Args&&... args) noexcept(noexcept(f(forward<Args>(args)...))) {
   
return f(forward<Args>(args)...);
 
}
};

The main difference with ptr_fun being that the function pointer is part of the type.



Motivation

The main motivating example is a unique_ptr that needs to call a custom deleter function. Currently (assuming you don't want to write some per-deleter boilerplate), you'd need to do something like:
std::unique_ptr<MyType, decltype(&myDeleter)> ptr(something, myDeleter);

This presents a few issues:
  1. You don't get to use the default constructor for unique_ptr. Not a big deal but it can be inconvenient.
  2. You aren't actually declaring a unique_ptr that calls the myDeleter function, you're declaring a unique_ptr that calls a function pointer with the same signature as the myDeleter function. If the object gets passed around a bit, the compiler won't be able to inline the deletion and you'll probably be left with an indirect call.
  3. For the same reason as issue 2, storing the function pointer doubles the size of the object.
I believe that:
std::unique_ptr<MyType, std::func_ptr<myDeleter>> ptr;
solves all of those issues.

Matt Calabrese

unread,
Apr 9, 2018, 11:46:44 AM4/9/18
to ISO C++ Standard - Future Proposals
On Mon, Apr 9, 2018 at 11:36 AM Hamza Sood <hamza...@me.com> wrote:
I propose the inclusion of a function object (somewhat similar to the deprecated ptr_fun) that looks something like:

template<auto f>
requires is_pointer_v
<decltype(f)> &&
         is_function_v
<remove_pointer_t<decltype(f)>>
struct func_ptr {
 
template<typename... Args>
 
decltype(auto) operator()(Args&&... args) noexcept(noexcept(f(forward<Args>(args)...))) {
   
return f(forward<Args>(args)...);
 
}
};

The main difference with ptr_fun being that the function pointer is part of the type.


I have proposed something like that here: http://wg21.link/p0477

It is awaiting a revision with some different names, and I will need to update it to target C++20 (updated constraints, etc.).

-- Matt Calabrese
Reply all
Reply to author
Forward
0 new messages