【问题标题】:C++ class that accepts function of any type as parameter接受任何类型的函数作为参数的 C++ 类
【发布时间】:2012-10-11 08:28:46
【问题描述】:

我正在为一个类编写一个 .hpp 文件,该类应该接收一个函数作为其参数之一并将其存储在一个成员变量中,到目前为止,我的代码如下所示:

template<typename Function> class myClass
{
  public:
           myClass(Function function) : pvFunction( function ) {}

           //Functor operator
           double operator() (double x) const{
             return pvFunction(x+4);
           }
  private:
           Function pvFunction
}

程序看起来毫无意义,因为它返回的值现在并不重要。我只是想弄清楚如何将一个函数传递给这个类并使用它的仿函数运算符。唯一的问题是:

1) 我不知道这个类的定义是否正确,意思是这是接受任何类型的函数作为参数传递给这个类的对象的正确方法。

2) 如何在我的程序中创建此类的实例?如何将函数传递给新对象然后调用它?

搞了这么久,还是搞不懂

编辑:

在我的程序文件 main.cpp 中,此代码收到错误:

double function(double);

int main()
{
   myClass<double> myClassObject((function));
   return 0;
}

double function(double x)
{
   return (x+3.0);
}

【问题讨论】:

  • 看看boost::function&lt;&gt;的实现以获得灵感。
  • 你的真正意思是“任何类型”还是“匹配某个参数类型列表和返回类型的任何类型”?

标签: c++ function templates implementation


【解决方案1】:

您收到错误,因为该类期望模板参数是实际的函数类型,但您在实例化中将模板参数作为double 传递。

考虑使用 C++11 的新功能,例如 std::function

template<typename T>
struct myClass
{
    typedef std::function<T(T)> func_type;

    func_type pvFunction;

    myClass(func_type func) : pvFunction(func) {}

    T operator()(T x)
        { return pvFunction(x + 4); }
};

double function(double x)
{
    return (x+3.0);
}

int main()
{
    myClass<double> my_class(function);
    std::cout << "my_class(3) = " << my_class(3) << '\n';
}

【讨论】:

  • 有意思,这样肯定更方便
【解决方案2】:

1) 是的。

2) 你的例子中myClassObject 的类型应该是

 myClass<double(*)(double)> myClassObject(function);

因为函数的类型是double(*)(double)。构造此类模板对象的最佳方法是使用这样的函数模板:

template<typename Function>
myClass<Function> MakeMyClass(Function f)
{
    return myClass<Function>(f);
}


int main()
{
   auto withFuncPtr= MakeMyClass(function);
   auto withLambda= MakeMyClass([] (double v) {return v*2;});

   Foo foo;
   auto withStdFunction = MakeMyClass(
       std::bind(&Foo::Method, &foo, std::placeholders::_1));
   return 0;
}

【讨论】:

  • 这正是我需要的,非常感谢
【解决方案3】:

您可以使用带有 operator() 的 struct 作为建议

template<typename Function> class myClass
{
  public:
        myClass(){}

        //Functor operator
        double operator() (double x) const
        {
          return pvFunction(x+4);
        }
  private:
        Function pvFunction;
};

struct Double
{
    double operator()(const double n)const
    {
        return n;
    }
};

int main() {
    myClass<Double> myClassObject;
    std::cout<<myClassObject(2.0f);
    return 0;
}

打印 6

【讨论】:

    【解决方案4】:

    我真的不确定你想要实现什么,因为如果你仍然想将任何函数绑定到具有双精度类型的参数,你怎么能使用它,但是,下面的示例使你的示例模板工作,但我实在看不出有什么用。

        template<typename Function> class myClass
        {
        public:
            myClass(Function function) : pvFunction( function ) {}
    
            //Functor operator
            double operator() (double x) const{
                return pvFunction(x+4);
            }
        private:
            Function pvFunction;
        };
    
        double foo1(double x)
        {
            return x;
        }
    
        double foo2(double x)
        {
            return x + 1;
        }
        int main(int argc, char** argv)
        {
            myClass<double(*)(double)> instance1(foo1);
            myClass<double(*)(double)> instance2(foo2);
            double a = instance1(1.5), b = instance2(1.5);
            return 0;
        }
    

    【讨论】:

    • 最终这将成为一个派生类,但我需要能够存储要先派生的函数。我不想让人们就如何实现一个接受函数派生的类提出建议,所以我把这些信息留了下来。
    猜你喜欢
    • 2021-10-18
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-08
    相关资源
    最近更新 更多