Maybe it's flu, or I'm just plain stupid, but I can't understand a part of this Crow framework code. My inner C++ parser fails.
template <typename MW>
struct check_before_handle_arity_3_const
{
template <typename T,
//this line
void (T::*)(int, typename MW::context&) const = &T::before_handle
>
struct get
{ };
};
I know it's a template parameter inside template declaration. It looks like maybe some lambda or function pointer type parameter... but, I'm not sure. Can someone explain this line?
Update: Exploring depths of newly obtained knowledge - after the answer was given - led me to this excerpt from a great book:
A template can accept a pointer to a function as a nontype template parameter. (Most often in this book, nontype template parameters are integral values.) [...] Using a pointer to a function as a nontype template argument means that we no longer need to store it in the map. This essential aspect needs thorough understanding. The reason we don't need to store the pointer to a function is that the compiler has static knowledge about it. Thus, the compiler can hardcode the function address in the trampoline code.
So, now I know one of the reasons to use this technique.
void (T::*)(int, typename MW::context&) const
is a non-type template parameter.
It is a pointer to a member function of T
.
With the use of = &T::before_handle
, its default value is set to &T::before_handle
.
The reason I used this technique is to support 2 kinds of handler format: https://github.com/ipkn/crow/blob/master/include/middleware.h#L17
check_before_handle_arity_3_const
is used here:
template <typename T>
struct is_before_handle_arity_3_impl
{
template <typename C>
static std::true_type f(typename check_before_handle_arity_3_const<T>::template get<C>*);
template <typename C>
static std::true_type f(typename check_before_handle_arity_3<T>::template get<C>*);
template <typename C>
static std::false_type f(...);
public:
static const bool value = decltype(f<T>(nullptr))::value;
};
With SFINAE, is_before_handle_arity_3_impl<T>::value
is determined whether we can call the handler with 3 arguments or not. By using std::enable_if
, Crow can call the proper handler:
https://github.com/ipkn/crow/blob/master/include/http_connection.h#L110
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With