也许是流感,或者我只是愚蠢,但我无法理解this Crow框架代码的一部分。我的内部C ++解析器失败了。
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
{ };
};
我知道它是模板声明中的模板参数。它看起来像是一些lambda或函数指针类型参数......但是,我不确定。 有人可以解释这一行吗?
更新 探索新获得的知识的深度 - 在给出答案之后 - 让我从一个伟大的book摘录:
模板可以接受指向函数的指针作为非类型模板 参数。 (本书中最常见的是非类型模板参数 积分值。)[...]使用指向函数的指针作为非类型 template参数意味着我们不再需要将它存储在地图中。 这个重要方面需要彻底了解。我们的原因 不需要存储指向编译器的函数的指针 关于它的静态知识。因此,编译器可以硬编码 蹦床代码中的函数地址。
所以,现在我知道使用这种技术的原因之一。
答案 0 :(得分:9)
void (T::*)(int, typename MW::context&) const
是非类型template parameter。
它是指向T
的成员函数的指针。
使用= &T::before_handle
时,其默认值设置为&T::before_handle
。
答案 1 :(得分:2)
我使用这种技术的原因是支持2种处理程序格式: https://github.com/ipkn/crow/blob/master/include/middleware.h#L17
这里使用 check_before_handle_arity_3_const
:
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;
};
使用SFINAE,is_before_handle_arity_3_impl<T>::value
确定我们是否可以使用3个参数调用处理程序。通过使用std::enable_if
,Crow可以调用正确的处理程序:
https://github.com/ipkn/crow/blob/master/include/http_connection.h#L110