指向成员函数类类型的指针

问题描述

class Object
{
public:
    void mem_func();
}

我希望能够在编译时从指向成员函数Object的指针中提取类型&Object::mem_func,但是没有注意到<type_traits>中可以用来获取类型的任何内容。类型。

这对于具有抽象数据成员的Pimpl类是理想的,该成员随后将其转换为非抽象类,具体取决于其公共类层次结构以与std::invoke配合使用。


编辑:,应Ilan Keshet的要求,并且由于Yakk-Adam Nevraumont提出的解决方案无法解决我拥有的额外间接层。

下面是我要做什么的更完整的想法。我想使用Qt的QAbstractSlider和QSlider类来实现范围滑块类。也许我以错误的方式来解决问题,如果是的话,请指导我采用更好的设计模式/策略来实现此目的。

// RangeSlider.h

class AbstractRangeSliderPrivate;
class AbstractRangeSlider : public QWidget
{
    Q_OBJECT
    Q_DECLARE_PRIVATE_D(d_ptr_,AbstractRangeSlider)

public:
    explicit AbstractRangeSlider(QWidget * parent = nullptr)
        : QWidget(parent),d_ptr_(new AbstractRangeSliderPrivate{ this,new QAbstractSlider{ this },new QAbstractSlider{ this } })
    {}

    virtual ~AbstractRangeSlider() override
    {}

    int minimum() const
    {
        Q_D(const AbstractRangeSlider);
        return d->getTemplate(&QAbstractSlider::minimum);
    }

    void setMinimum(int min) const
    {
        Q_D(AbstractRangeSlider);
        return d->setTemplate(&QAbstractSlider::setMinimum,min);
    }

    int maximum() const;
    void setMaximum(int max);
    //... etc

protected:
    AbstractRangeSlider(AbstractRangeSliderPrivate & dd,QWidget * parent)
        : QWidget(parent)
        : d_ptr_(&dd)
    {
    }

    QScopedPointer<AbstractRangeSliderPrivate> const d_ptr_;
};

class RangeSliderPrivate;
class RangeSlider : public AbstractRangeSlider
{
    Q_OBJECT
    Q_DECLARE_PRIVATE_D(d_ptr_,RangeSlider)

public:
    RangeSlider(QWidget * parent = nullptr)
        : AbstractRangeSlider(new RangeSliderPrivate{ this,QSlider{ this },QSlider{ this } },parent)
    {
    }

    virtual ~RangeSlider() override
    {
    }

    // These need to be cast from QAbstractSlider in the get/setTemplates
    // since these member functions are only in the derived slider class.
    QSlider::TickPosition tickPosition() const
    {
        Q_D(RangeSlider);
        return d->getTemplate(&QSlider::tickPosition);
    }

    void setTickPosition(QSlider::TickPosition position)
    {
        Q_D(RangeSlider);
        return d->setTemplate(&QSlider::setTickPosition,position);
    }

    // etc
};





// RangeSlider_p.h
#include "AbstractRangeSlider.h"
#include <QAbstractSlider>
#include <utility>

class AbstractRangeSliderPrivate
    : public MixinPrivate<AbstractRangeSliderPrivate,QAbstractSlider>
{
    Q_DECLARE_PUBLIC(AbstractRangeSlider)

public:
    AbstractRangeSlider * q_ptr;

    AbstractRangeSliderPrivate(AbstractRangeSlider * q)
        : q_ptr(q)
    {}

    ~AbstractRangeSliderPrivate()
    {}

    void init(QAbstractSlider * lowSlider,QAbstractSlider * highSlider_)
    {
        lowSlider_ = lowSlider;
        highSlider_ = highSlider;
    }

    template <typename Func>
    auto getTemplate(Func func) const
    {
        // I want to cast these from AbstractRangeSlider to a concrete type such as QSlider when necessary
        assert(std::invoke(func,static_cast<???>(lowSlider_))) == std::invoke(func,static_cast<???>(highSlider_)));
        return std::invoke(func,static_cast<???>(lowSlider_));
    }

    template <typename Func,typename... Args>
    void setTemplate(Func func,Args && ... args)
    {
        std::invoke(func,static_cast<???>(lowSlider_)),std::forward<Args>(args)...);
        std::invoke(func,static_cast<???>(highSlider_)),std::forward<Args>(args)...);
    }

    AbstractRangeSlider * lowSlider_;
    AbstractRangeSlider * highSlider_;
};

解决方法

template<auto x>
struct memfunc_object;
template<auto x>
using memfunc_object_t=typename memfunc_object<x>::type;
template<class T,class R,class...Args,R(T::*mf)(Args...)>
struct memfunc_object< mf > {
  using type=T;
};

live example

需要

没有它,您可以执行decltype(&bob::hello)并编写类似的特征类以提取T

template<class M>
struct memfunc_t_object;
template<class M>
using memfunc_t_object_t=typename memfunc_t_object<M>::type;
template<class T,class...Args>
struct memfunc_t_object< R(T::*)(Args...) > {
  using type=T;
};

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...