C++可变参模板优雅的表示函数指针

目的

我们的是将函数指针
R(T::*ptr)(Args...)这种形式
变成 Functor<Args...>(ptr) 这种形式
在一个同名函数有多个重载方法的时候,这样的方式会比较优雅。
Functor是一个结构体或者类

RT,这里是从Qt的源码中学到的,防走丢,上代码

代码

template <typename... Args>
struct QNonConstOverload
{
    
    
    template <typename R, typename T>
    Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
    {
    
     return ptr; }

    template <typename R, typename T>
    static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
    {
    
     return ptr; }
};

template <typename... Args>
struct QConstOverload
{
    
    
    template <typename R, typename T>
    Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...) const) const Q_DECL_NOTHROW -> decltype(ptr)
    {
    
     return ptr; }

    template <typename R, typename T>
    static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...) const) Q_DECL_NOTHROW -> decltype(ptr)
    {
    
     return ptr; }
};

template <typename... Args>
struct QOverload : QConstOverload<Args...>, QNonConstOverload<Args...>
{
    
    
    using QConstOverload<Args...>::of;
    using QConstOverload<Args...>::operator();
    using QNonConstOverload<Args...>::of;
    using QNonConstOverload<Args...>::operator();

    template <typename R>
    Q_DECL_CONSTEXPR auto operator()(R (*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
    {
    
     return ptr; }

    template <typename R>
    static Q_DECL_CONSTEXPR auto of(R (*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
    {
    
     return ptr; }
};

简单解释下

  • 变参定义: typename… 或者 class… ,template尖括号里的Args 相当于是一个类型变量名,然后下面用到可变参的时候,也要加 ‘’,也就是说,可变参的类型一定要后面加 ‘’。我可能说的不太对,意思就那个意思。可变参可以看下这个链接:https://www.cnblogs.com/qicosmos/p/4325949.html
  • 万能推导
template <typename R, typename T>
auto of(R (T::*ptr)(Args...) const) Q_DECL_NOTHROW -> decltype(ptr)

拿这个举个例子,知道lamda表达式的肯定都懂,*’->decltype(ptr)’*其实就是声明返回值类型,这样前面的auto就能推导ptr的类型。然后这个 *R (T::*ptr)(Args…)*就是一个万能函数,函数指针不就是这么声明的吗?

  • using,其实这3个结构体形式都差不多,只不过模板参数,const 非const等有些区别,最终使用QOverload就可以了,使用using就是解决基类和派生类同名函数的问题,不懂的可以参考https://zhuanlan.zhihu.com/p/161039484

使用例子

//QProcess中有这样一个函数

void 
QProcess::finished(int exitCode, QProcess::ExitStatus exitStatus);

QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished)
//其中,int  QProcess::ExitStatus是参数类型,这里其实of省略了模板参数<void,QProcess>,一个是返回值类型,一个是类名,编译器推导出来了
QOverload<int, QProcess::ExitStatus>::of<void,QProcess>(&QProcess::finished)
//这是完整的形式

猜你喜欢

转载自blog.csdn.net/qq_16952303/article/details/118153099
今日推荐