-1

我有一个带有数组的类,其大小在构造函数中指定。该类还存储了一个指向函数的指针,该函数将指针作为参数,调用时将设置为指向数组。我还有一个“绑定”函数,它将函数指针设置为等于作为参数传入的某个其他函数。这允许我绑定参数将包含数组的任意函数。它看起来像这样:

template <typename T>
class MyClass{
public:
    MyClass(int s) : size(s) { arr = new T[size]; }
    MyClass() { delete[] arr; }

    virtual inline void bindFunc(void(*func)(T[])) { fn = func; } //types match, ok
    inline void callFunc(){fn(arr);} 
        /*Yes, I know I need a size parameter to correctly
        iterate over arr, I took out this info to help make things more clear, just pretend 
        arr is null terminated and the bound fn function knows how to correctly handle it*/

private:

    const int size; 
    T arr[];
    void(*fn)(T[]);
};

这一切都很好,但是使用数组(或任何容器类型)的重点是,从 MyClass 继承的类可以指定显式大小。然后,我计划(以某种方式)覆盖 bindFunc 函数以获取指向具有显式数量的单独参数的函数的指针,而不是指向具有参数数组的函数的指针。这只是为了清理语法并使派生类隐藏实现。它看起来像这样:

class derived: public MyClass<double> {
public:
    derived() : MyClass(2) {}

    inline void bindFunc(void(*func)(double, double)) { fn = func; } //error, type mismatch, obviously
};

错误发生在fn = func因为 fn 是指向以数组(指针)作为参数的函数的指针,而 func 是指向以 2 个双精度为参数的函数的指针。这是我不知道如何解决的问题的症结所在。

当然,在这个片段中,我稍微精简了代码,只包含相关部分,并重命名了所有内容以更好地描述我的问题。如果有帮助,该类的最初目的是存储从 GLFW 的回调函数传入的状态信息。派生类应该分别保存滚动和鼠标位置信息(1 个元素用于滚动位置,2 个元素用于鼠标 X/Y 位置,因此数组的大小在派生类的构造函数中设置。)基类还具有计算其他事物的功能,例如任何其他可想象的变量输入类型都会发现有用的增量,因此是层次结构抽象。这一切都是为了简化输入处理,并且在使用时看起来像这样:

void mouse_callback(GLFWwindow*, double, double);
glfwSetCursorPosCallback(window, mouse_callback);

MyClass *MouseInput = new derived;

void mouseFunction(double x, double y){ //takes 2 doubles instead of array of doubles of size 2
    if(x > 0.5)
        //do something
    if(y < 0.5)
        //do something else
}

void main(){
    MouseInput->bindFunc(mouseFunction);
    MouseInput->callFunc();
}

void mouse_callback(GLFWwindow* window, double xpos, double ypos) {
    MouseInput->setInfo(xpos, ypos);
        /*this function is not shown in the code above, but it basically sets
        MouseInput->arr's variables and calls a base class' calculation function
        to calculate extra info such as the aforementioned deltas*/
}

我不确定我想要的是否可能,但我有兴趣了解更多关于它或更正确的设计模式。我试过摆弄 <functional>函数,但我自己想不出任何东西。感觉语言会有一个特性可以让这样的事情成为可能,这就是为什么我想一开始就输入这个问题。

我在 C++ 中尝试的大部分内容都是为了学习,我知道我的方法对于我想要完成的事情可能有点疯狂,但希望它会导致成为一个更好的程序员。提前感谢您的洞察力!

4

1 回答 1

1

如果您使用std::function原始函数指针而不是原始函数指针,则可以使用 lambda 以任何您想要的方式转换参数:

template <typename T>
class MyClass{
    std::function<void(T[])>  fn;
public:

virtual inline void bindFunc(void(*func)(T[])) { fn = func; } //types match, ok
virtual inline void bindFunc(void(*func)(T, T)) {
    fn = [func](T args[]) { func(args[0], args[1]); }; }

为了获得更大的灵活性,您也可以将func参数std::function设为a

于 2018-07-03T00:03:20.277 回答