convert function types

Hi,

i am new to c++ programming and need help. The following code is an short example of the problem

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>

class A {
public:
  std::string f(int i) {
    return g(i);
  }
private:
  std::string g(int i) {
    return "A.g " + std::to_string(i);
  }
};

int main() {
  A a;
  std::cout << a.f(1) << std::endl;
}


Given is a class A and the class has a member function names g. The function g is used in another member function f. I want to modify the class such that I can swap the function g with an arbitrary other function.
My idea was to create a pointer p which points to the function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A {
public:
  using fct_type = std::string (int);
  A(fct_type *custom)
    : p(custom)
  {}

  std::string f(int i) {
    return p(i);
  }
private:
  // ...
  fct_type *p;
};

int main() {
  A a([](int) { return std::string("arg"); });
  std::cout << a.f(1) << std::endl;
}

This code still compiles and does what it should do. My problem is to set a default argument for the constructor:
1
2
3
A(fct_type *custom = &A::g)
    : p(custom)
  {}

The type of the default argument is std::string (A::*)(int) and not std::string (*)(int).
My question is how can I convert to type or is there another way of solving my problem? (Furthermore is efficiency a requirement. The function f is called often.)
Last edited on
Wrap in a call wrapper http://en.cppreference.com/w/cpp/utility/functional/function
and bind the this pointer for member functions http://en.cppreference.com/w/cpp/utility/functional/bind

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <string>
#include <functional>

struct A {

    using fct_type = std::function< std::string(int) > ; // wrapped non-member function
    using mem_fct_type = std::function< std::string( const A*, int ) > ; // wrapped const member or binary function

    fct_type p ;

    // construct with member function which take one argument int
    //           or non-member function which takes two arguments const A*, int
    // default is: &A::g
    explicit A( mem_fct_type mem_fct = &A::g ) : p( std::bind( mem_fct, this, std::placeholders::_1 ) ) {}

    A( fct_type custom ) : p(custom) {} // construct with non-member function

    std::string f( int i ) { return p(i) ; }

    std::string g( int i ) const { return "A::g " + std::to_string(i+v) ; }
    std::string h( int i ) const { return "A::h " + std::to_string( (i+v)*2 ) ; }

    int v = 7 ;
};

int main() {

    A one ;
    std::cout << one.f(23) << '\n' ; // A:g 30 (23+7)

    A two( &A::h ) ;
    std::cout << two.f(23) << '\n' ; // A::h 60 ( (23+7)*2 )

    A three( []( int i ) { return "main::closure " + std::to_string(i*3) ; } ) ;
    std::cout << three.f(23) << '\n' ; // main::closure 69 (23*3)

    A four( []( const A* pa, int i ) { return "main::closure two " + std::to_string( (i+pa->v) * 4 ) ; } ) ;
    std::cout << four.f(23) << '\n' ; // main::closure two 120 ( (23+7)*4 )
}

http://coliru.stacked-crooked.com/a/14d4615efddb1b22
Thank you very much. I already found std::bind but I did not know about std::function.
Also thank you for the small example which makes it easier to understand.
Topic archived. No new replies allowed.