简体   繁体   English

在C ++中以函数为参数的构造函数

[英]Constructors with functions as arguments in C++

I got some objects which variables rely on different functions. 我得到了一些变量依赖于不同功能的对象。 To put it in different words: There are multiple types of functions on which the variables in the object rely, but there should be multiple objects with same of these functions. 换句话说:对象中的变量依赖多种功能,但是应该有多个具有相同功能的对象。 For more clearance I tried to give an example (which does not work). 为了获得更多的许可,我尝试给出一个示例(不起作用)。

#include <iostream>

class A
{
  double size;

  A( double (*f)() )
  {
    size = (*f)();
  };
};

double fun1()
{
  return 42.0;
}


int main()
{
  A a = A( &fun1() );

  std::cout << a.size << std::endl;
}

This is of course a minimal example. 这当然是一个最小的例子。 The variable size depends on a certain function which should be passed as an argument to the class. 变量的大小取决于某个函数,该函数应作为参数传递给类。 Imagine fun1 and fun2 as different kinds of random number generators. 可以将fun1fun2想象成不同种类的随机数生成器。

I think that the ideomatic way in C++ would be a class which holds the variable and the classes inherited from it are modified by that function that differs the objects (please correct me if I'm wrong with this assumption). 我认为C ++中的意识形态方法将是一个包含变量的类,并且从该类继承的类将由与对象不同的函数进行修改(如果我对此假设有误,请纠正我)。 But my question is: 但是我的问题是:

Is there any possibility to implement some kind of higher-order constructor? 是否有可能实现某种高阶构造函数? If so, an example would be nice. 如果是这样,那么一个例子会很好。

ps: If I used some technical terms wrong, I'd be glad to be corrected. ps:如果我用错了一些技术术语,很高兴得到纠正。

Change to: 改成:

A( double (*f)() )
{
    size = f();
};

And: 和:

A a = A( fun1 );

When you were passing &fun1() that was trying to call the function and then take the address of its result. 当您传递&fun1() ,它试图调用该函数,然后获取其结果的地址。 What you actually wanted was the function pointer itself which is stored in fun1 . 您真正想要的是存储在fun1的函数指针本身。

This example is meaningless, because you don't save the function pointer for later use. 这个例子是没有意义的,因为您不保存函数指针供以后使用。 You can rewrite this simply to just 您可以将其简单地重写为

class A
{
    double size;

    A(double sz) {
        size = sz;
    };
};

double fun1()
{
    return 42.0;
}


int main()
{
    A a = A(fun1());
    std::cout << a.size << std::endl;
}

I suggest writing a template instead so you can pass in any function pointer or function object. 我建议改为编写模板,以便您可以传入任何函数指针或函数对象。 This allows the compiler to more easily do optimisations like inlining in many cases, and is more flexible. 在许多情况下,这使编译器可以更轻松地进行优化(如内联),并且更加灵活。 You should also not use parentheses when acquiring a function pointer. 获取函数指针时,也不应使用括号。

#include <iostream>

class A {
public:
    template<typename F>
    explicit A(F&& f) : size(f()) {

    };

    double size;
};

double fun1() {
    return 42.0;
}

int main() {
    A a(&fun1);
    std::cout << a.size << std::endl;
}

Looks like you need only the function itself to be passed. 看起来您只需要传递函数本身。 You've almost got it. 你差不多了。 Here is the correct syntax: 这是正确的语法:

typedef double (*functype)();

void foo(functype f) {
    cout << f();
}

double bar() {
    return 2.39;
)

foo(bar); // don't call bar here, just pass it as address.

You can also declare foo as follows: 您还可以如下声明foo:

void foo(double (*f)());

Functions are not first-class objects in C++, so the only way to create a closure with some variables (for example, if you want to carry the function or call a non-static member function) is functors (objects with overloaded operator() ). 函数不是C ++中的一流对象,因此创建带有某些变量的闭包的唯一方法(例如,如果您要携带函数或调用非静态成员函数)是仿函数(带有重载operator()的对象) )。 There are several ways of getting such object: 有几种获取此类对象的方法:

  1. Define it by yourself, store all necessary variables in fields and pass it as function's argument. 自己定义,将所有必需的变量存储在字段中,并将其作为函数的参数传递。
  2. Use C++11's lambda functions and std::function 使用C ++ 11的lambda函数和std :: function
  3. Use boost::function and boost::bind. 使用boost :: function和boost :: bind。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM