0

I'm writing a little game that works on a 2D tileset. The idea is that there will be some cells (position X, position Y) where if the player steps, it will trigger an event, so I'm creating a map<cell_position, function to trigger>.

The problem is that this function it will be in the World class, that contains the Npc member, and I want to store the Npc public function teleport as the value from the map, as I can display in the next snippet:

std::unordered_map<std::pair<int, int>, std::function<void()>> actionCells =
 { std::make_pair(10, 1), std::bind(mPlayerNpc->teleport, 3, 3)) };

Is this possible to do? Because I'm getting the next errors:

error: invalid use of non-static member function 'void Npc::teleport(int, int)'

--Edit-----------------------------------

If I don't want to use a Lambda, is it done like this?

std::unordered_map<std::pair<int, int>, std::function<void()>> actionCells =
   { std::make_pair(10, 1), [&]() {mPlayerNpc->teleport(3, 3); } };
Albert Lazaro de Lara
  • 2,540
  • 6
  • 26
  • 41
  • `mPlayerNpc.teleport` does not correctly describe the instance `teleport` needs to be invoked upon. You want something more like `&TYPE::teleport, &mPlayerNpc` to specify the function being invoked and the the instance. That said, look into using a [Lambda expression](https://en.cppreference.com/w/cpp/language/lambda) instead of `std::bind`. Lambda is usually easier to wrangle and has less runtime overhead. – user4581301 Dec 20 '21 at 20:30
  • Yes, it's possible. When using `std::bind` with non-static members, you need an instance to bind against, by reference, address, or placeholder if need be. You're not doing any of those. – WhozCraig Dec 20 '21 at 20:41
  • @user4581301 I have edited the post and I have added how I would do with a lambda expression. Do you have any examples of how to do? – Albert Lazaro de Lara Dec 20 '21 at 20:51
  • Your issue is entirely about how to use `std::bind` to call a member function, which is answered in plenty of questions such as https://stackoverflow.com/questions/37636373/how-stdbind-works-with-member-functions – Tas Dec 20 '21 at 20:54

1 Answers1

1

Passing class instance to std::bind should work. Something like:

std::unordered_map<std::pair<int, int>, std::function<void(int x, int y)>> actionCells =
 { std::make_pair(10, 1), std::bind(&ActualClassNameOfPlayerNpc::teleport, mPlayerNpc 3, 3)) };
no more sigsegv
  • 468
  • 5
  • 17
  • 1
    Fair warning: this will invoke copy semantics against mPlayerNpc. If that isn't desirable, and scope management dictates it, either pass by address or shroud the instance in a reference wrapper and be wary of mPlayerNpc lifetime. – WhozCraig Dec 20 '21 at 20:46
  • Yes, good heads up. I assumed that it is a pointer. – no more sigsegv Dec 20 '21 at 20:53
  • Because of the error message, can we assume the class name for `mPlayerNPc` is in fact `Npc`? – Tas Dec 20 '21 at 20:55
  • I changed it to `ActualClassNameOfPlayerNpc` since we don't know what the actual class name is. So you are correct. – no more sigsegv Dec 20 '21 at 20:57