Question

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.

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). But my question is:

Is there any possibility to implement some kind of higher-order constructor? If so, an example would be nice.

p.s.: If I used some technical terms wrong, I'd be glad to be corrected.

Was it helpful?

Solution

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. What you actually wanted was the function pointer itself which is stored in fun1.

OTHER TIPS

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:

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() ). 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
  3. Use boost::function and boost::bind.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top