【问题标题】:Passing an inherited method to another method将继承的方法传递给另一个方法
【发布时间】:2016-02-13 20:25:32
【问题描述】:

我正在尝试构建一个具有以方法作为参数的成员函数的类。这些方法在继承的类中定义。我建立了一个最小的例子:

#include <iostream>

struct base
{
    base() {}

    int number(int (*f)(int))
    {
        return f(1);
    }
};

struct option1 : base 
{
    int timesTwo(int i){return 2*i;}
    option1() 
    {
        std::cout << number(timesTwo);
    }
};

struct option2 : base
{
    int timesThree(int i){return 3*i;}
    int timesFour (int i){return 4*i;}
    option2() 
    {
        std::cout << number(timesThree);
    }
};

int main()
{
    option1 a; //I would expect this to print "2"
}

函数number 中的当前语法适用于一般函数,但我无法让它适用于任何继承类的方法。

【问题讨论】:

    标签: c++ inheritance methods


    【解决方案1】:

    这里的问题是您传递一个指向 member 函数的指针,这与指向非成员函数的指针完全不同(这是您的 number 函数所采用的论据)。

    您可以使用std::functionstd::bind

    int number(std::function<int(int)> f)
    {
        return f(1);
    }
    
    ...
    
    number(std::bind(&option1::timesTwo, this, _1));
    

    你也可以使用模板和额外的参数,比如

    template<typename T>
    int number(T* object, int(T::*f)(int))
    {
        return (object->*f)(1);
    }
    
    ...
    
    number(this, &option1::timesTwo);
    

    或者简单的(但并不总是正确的,取决于情况和用例):制作回调函数static

    static int timesTwo(int i){return 2*i;}
    

    我的建议是您使用 std::function 查看解决方案,因为这样可以轻松地使用任何类型的可调用对象(例如 lambda)调用 number 函数:

    number([](int x){ return x * 2; });
    

    【讨论】:

    • 谢谢!如果我担心只添加static 的解决方案,您能否详细说明?我知道使用std::function 更通用,但我很确定在任何其他情况下我都不必调用该函数。
    • @RobVerheyen 如果您传递的函数将永远不会访问它定义的类中的任何非静态成员,那么您可以毫无顾虑地将其设为static
    【解决方案2】:

    给定的错误说:

    错误:必须调用非静态成员函数的引用

    您可以在方法成员之前添加static

    我建议您使用std::function 而不是指针函数。

    工作代码:

    #include <iostream>
    #include <functional>
    
    struct base
    {
        base() {}
    
        int number(std::function<int(int)> f)
        {
            return f(1);
        }
    };
    
    struct option1 : base 
    {
        static int timesTwo(int i){return 2*i;}
        option1() 
        {
            std::cout << number(timesTwo);
        }
    };
    
    struct option2 : base
    {
        static int timesThree(int i){return 3*i;}
        static int timesFour (int i){return 4*i;}
        option2() 
        {
            std::cout << number(timesThree); 
        }
    };
    
    int main()
    {
        option1 a; // now it works
    }
    

    【讨论】:

    • 谢谢。考虑到代码很可能不再需要上述任何方法,是否有任何理由特别在指针上使用std::function
    • @RobVerheyen 你应该看看therethere。它更像 C++,但您可以坚持使用您的解决方案。我认为更重要的是你应该重新设计你的代码。
    猜你喜欢
    • 2014-08-11
    • 1970-01-01
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 2020-07-29
    • 1970-01-01
    相关资源
    最近更新 更多