Per Object Function

Hello!
This is a quick one, is there any way to make a class with a member function that gets defined by the object itself?
For example:


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
#include <iostream>

class MyClass
{
 public:
 MyClass();
 void something();

};

MyClass m1(),m2();

void m1::something()
{
 std::cout<<"Hello";
}

void m2::something()
{
 std::cout<<" World!\n";
}

int main()
{
 m1.something();
 m2.something(); //Different result

 return 0;
}


Is this possible?

Thanks! :)

Last edited on
This yields same output as your pseudo:
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
#include <iostream>
#include <string>

class MyClass
{
  std::string msg;
public:
 MyClass( const std::string& );
 void something();
};

MyClass::MyClass( const std::string& txt )
 : msg( txt )
{}

void MyClass::something()
{
 std::cout << msg;
}

int main()
{
 MyClass m1( "Hello" );
 MyClass m2( " World!\n" );
 m1.something();
 m2.something();
}
Hey @keskiverto, thanks for replying

This is a nice solution for that specific problem. I want to be able to make an entirely different definition for each object.

Something like that:

1
2
3
4
5
6
7
8
9
10
11
12
void m1::something()
{
 std::cout<<"Hello world!\n";
}

void m2::something()
{
int a =16,,b=10;
float c= (a+b)/2;

}
Last edited on
The type std::function<void()> represents the set of functions returning nothing and accepting no parameters.

Add a data member of this type.
1
2
3
4
5
6
7
8
9
10
11
12
#include <functional>
#include <iostream>

struct foo { std::function<void()> something; };
foo a{[]() { std::cout << "hello\n"; }};
foo b{[]() { std::cout << "goodbye\n"; }};

int main()
{
    a.something();
    b.something();
}
An another approach to polymorphism is inheritance:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

struct foo {
    virtual void something()
    { std::cout << "hello\n"; }
};

struct bar : public foo {
    virtual void something()
    { std::cout <<  (6 * 7) << '\n'; }
};

int main()
{
    foo a;
    bar c;
    foo& b = c;
    a.something();
    b.something();
}
By the way, the use of std::function or function pointers (not shown here, but basically the same thing but with worse syntax), is commonly called a "callback" function, where a function calls another function that was passed into it.
https://stackoverflow.com/questions/2298242/callback-functions-in-c
is there any way to make a class with a member function that gets defined by the object itself?

I want to be able to make an entirely different definition for each object.

I don’t think you’re really doing your best to make your life unnecessarily tough. I think you should try harder.
For example:
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <type_traits>


template <typename T, typename K> struct Nothing;
template <typename T, typename K>
std::ostream& operator<< (std::ostream&, const Nothing<T, K>&);


template <typename T, typename K> struct Nothing {
    K something() const;
    K operator()(const K&) const;
    friend std::ostream& operator<< <>(std::ostream&, const Nothing<T, K>&);
};


template <typename T, typename K> K Nothing<T, K>::something() const
{
    return T()();
}


template <typename T, typename K> K Nothing<T, K>::operator()(const K& val) const
{
    return T()(val);
}


template <typename T, typename K>
std::ostream& operator<< (std::ostream& os, const Nothing<T, K>& rhs)
{
    os << rhs.something();
    return os;
}


template <typename T> struct Something {
    template <typename K = T>
    std::enable_if_t <std::is_integral_v<K>, K> operator() () const;
    template <typename K = T>
    std::enable_if_t <std::is_floating_point_v<K>, K> operator() () const;
};


template <typename T>
template <typename K>
std::enable_if_t <std::is_integral_v<K>, K> Something<T>::operator()() const
{
    return 299792458;
}


template <typename T>
template <typename K>
std::enable_if_t <std::is_floating_point_v<K>, K> Something<T>::operator()() const
{
    return 3.141592653589793238462643383279502884197169399375105820974944;
}


auto anything { [](const auto& val) -> bool { return val % 2; } };


int main()
{
    std::cout << "The speed of light in vacuum is "
              << Nothing<Something<int>, int>()
              << " m/s,\nthe greek PI is approximately "
              << Nothing<Something<double>, double>()
              << ",\nand 13 is "
              << ( Nothing<decltype(anything), bool>()(13) ? "odd" : "even" )
              << '\n';
}


Output:
The speed of light in vacuum is 299792458 m/s,
the greek PI is approximately 3.14159,
and 13 is odd

Thanks so much for replying to everyone!

I find @mbozzi's approach the best for me actually. I want to avoid having to make an entirely new class/struct just for changing that function @keskiverto, but thanks anyway.

@Enoizat, thanks for your invested reply but I'm not really that familiar with templates yet so it would be helpful if you can explain what's going on in that code (sorry!).
it would be helpful if you can explain what's going on in that code

I was just kidding and that code was for fun; those are a lot of lines for merely outputting little data on screen. I just meant there are many complicated ways to accomplish pretty simple tasks.

Do go with mbozzi’s solution, of course — that’s perfect.

What you asked was how to provide the users of your code with an object that changes behaviour according to… something that’s not that clear.
MyClass a;
MyClass b;
a.mymethod(); --> does something
b.mymethod(); --> does a totally different thing

Imagine to be required to document it: what would you write? Are you sure in six months’ time you’ll remember what you did?

Even if mbozzi’s solution is the tersest, note that keskiverto’s one requires at least to change the type name (from the base to the derived).
If you used templates, at least there would be ‘something’ which could give some clues about what ‘sort of type’ you’re dealing with in a specific moment (will behave like ‘a’ or ‘b’?)


But, hey, this is your code. You decide on what path to follow.
Ok, sorry for not being clear enough

In the game engine I'm currently building I have a 'Scene' class. Now, in that class, I have a function called 'Run()' which gets called every game loop. Because I want a number of scenes in my game I want to have an undefined function ('Run()') that gets defined by the scene object itself and thus make myself able to have a number of scene objects having their 'Run()' function do different things.

What you asked was how to provide the users of your code with an object that changes behavior according to…


I want the object to define the function so every object can define it's 'Run()' function differently.

Thanks! :D
That sounds like the callback pattern would be best. You just pass in the run function that you want to use for each one, probably in the ctor, and then it will simply work.
Imagine to be required to document it
It can be documented like any other runtime-polymorphic interface.

Note that keskiverto’s one requires at least to change the type name (from the base to the derived).
What's the advantage of changing the type name if some interface is going to forget it anyway? If this doesn't happen, runtime polymorphism is unnecessary: don't pay for it if not required.

@keskiverto's suggestion yields very simple code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <memory>

struct bar { virtual void operator()() const = 0; };

struct foo 
{
  template <typename T>
  explicit foo(T const& x) : impl_(std::make_shared<T>(x)) {}
  void operator()() const { return (*impl_)(); }
private:
  std::shared_ptr<bar const> impl_;
};

struct baz : bar { void operator()() const override { std::cout << "Hello\n"; } };
struct qux : bar { void operator()() const override { std::cout << "Goodbye\n"; } };

struct my_class { foo f; }; 

int main()
{
  my_class a{foo{baz{}}}; a.f();
  my_class b{foo{qux{}}}; b.f();
} 

That's not bad at all. But it does require the user to inherit from some known base class, which is occasionally a significant burden.

This is very closely related to std::function, which takes additional steps to hide the inheritance and provide value-semantics:
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
41
42
43
44
#include <iostream>
#include <memory>

struct foo
{
  void operator()() { basis_->operator()(); }
 
  template <typename T>
  foo(T x): basis_(std::make_unique<model<T>>(std::move(x))) {}
  foo(foo const& other): basis_(other.basis_->clone()) {}
  foo(foo&&) = default;
  foo& operator=(foo const& rhs) { basis_ = rhs.basis_->clone(); return *this; }  
  foo& operator=(foo&&) = default;
  
private:
  struct basis 
  { 
      virtual void operator()() = 0;
      virtual std::unique_ptr<basis> clone() const = 0;
  }; 
  
  template <typename T> struct model : basis 
  {
    explicit model(T const& x) : impl_(x) {}
    void operator()() override { impl_(); }
  
    std::unique_ptr<basis> clone() const override 
    { return std::make_unique<model<T>>(impl_); }
    
  private:
    T impl_; 
  };
  
  std::unique_ptr<basis> basis_;
};

struct my_class { foo f; };

int main()
{
  my_class a{[]() { std::cout << "Hello\n"; }}; a.f();
  my_class b{[]() { std::cout << "Goodbye\n"; }}; b.f();
}
std::function helps to contain the tight coupling and reference semantics associated with inheritance to a small chunk of library code.
Last edited on
I want a number of scenes in my game I want ... scene objects having their 'Run()' function do different things.

Data and action.

Is it ideal to have:
1
2
3
4
5
6
7
8
struct Scene {
  function object Run
};

Scene forest[2];
forest[0].Run = run1;
forest[1].Run = run2;
for ( auto f : forest ) f.Run();

Do all scene objects have some data members (in addition to the 'Run')?
How would the 'Run' access that data?


Lets take two scenes. Both have trees. One could have two functions:
1
2
run1() { // draws large green trees }
run2() { // draws small pink trees } 

Or a parametrized function:
1
2
3
run( sz, co ) {
 // draws trees with size 'sz' and colour 'co'
}

Or its data-and-method-together version:
1
2
3
4
class Scene {
  sz, co
  run() { // draws trees with size 'sz' and colour 'co' }
};

That obviously breaks down if we want cars, unless:
1
2
3
4
class Scene {
  sz, co, type
  run() { // draws objects of 'type' with size 'sz' and colour 'co' }
};

Now we can have Scene a{large,green,tree}, b{small,red,car}
but that makes the run() complex
1
2
3
4
5
6
7
class Scene {
  sz, co, type
  run() { type( sz, co ); }
};

void car( size, colour ){ // draws cars }
void tree( size, colour ){ // draws trees } 

This last version of run() can do some common operations in addition to calling the differentiating function object and data is passed from scene to type().
Thanks everyone for the help!
I think I will go with @mbozzi approach.

@keskiverto, your way works fine but it can get really messy when doing very different things in Run(), but thanks anyways.

Thanks again!
Topic archived. No new replies allowed.