Member Function Pointers and Binding

std::mem_fn() and Code Readability

How does using std::mem_fn() improve code readability compared to raw function pointers?

Abstract art representing computer programming

Using std::mem_fn() can significantly improve code readability compared to raw function pointers in several ways:

Simplified Syntax

std::mem_fn() eliminates the need for the sometimes confusing pointer-to-member syntax (.* or >*). This makes the code more intuitive and easier to read, especially for developers less familiar with these operators.

#include <functional>

class Player {
 public:
  int getScore() { return score; }

 private:
  int score = 100;
};

int main() {
  // Using raw function pointer
  int (Player::*rawPtr)() = &Player::getScore;
  Player p;
  int score1 = (p.*rawPtr)();

  // Using std::mem_fn
  auto memFn = std::mem_fn(&Player::getScore);
  int score2 = memFn(p);
}

Consistency with Standard Library

std::mem_fn() returns a function object that's consistent with other standard library function objects. This allows it to be used seamlessly with algorithms and other parts of the standard library.

#include <algorithm>
#include <functional>
#include <vector>

class Enemy {
 public:
  int getHealth() { return health; }

 private:
  int health = 100;
};

int main() {
  std::vector<Enemy> enemies(10);
  std::vector<int> healths(10);

  // Easy to use with standard algorithms
  std::ranges::transform(
    enemies,
    healths.begin(),
    std::mem_fn(&Enemy::getHealth)
  );
}

Type Deduction

std::mem_fn() can deduce the type of the member function, which can lead to more concise and less error-prone code, especially when dealing with complex class hierarchies or templated classes.

Uniform Function Call Syntax

std::mem_fn() provides a uniform way to call member functions, regardless of whether you're dealing with an object, a pointer, or a smart pointer.

#include <functional>
#include <iostream>

class Widget {
 public:
  void doSomething() {
    std::cout << "Doing something\n";
  }
};

int main() {
  auto doIt = std::mem_fn(&Widget::doSomething);

  Widget w;
  Widget* pw = &w;
  std::unique_ptr<Widget> upw =
    std::make_unique<Widget>();

  doIt(w);    // Object
  doIt(pw);   // Pointer
  doIt(upw);  // Smart pointer
}
Doing something
Doing something
Doing something

Better Integration with Functional Programming

std::mem_fn() creates function objects that work well with other functional programming tools in C++, such as std::bind() and lambda expressions.

#include <functional>
#include <iostream>

class Greeter {
 public:
  void greet(const std::string& name) {
    std::cout << "Hello, " << name << "!\n";
  }
};

int main() {
  Greeter g;
  auto greetFn = std::mem_fn(&Greeter::greet);

  // Can be easily used with std::bind
  auto greetAlice =
    std::bind(greetFn, &g, "Alice");

  greetAlice();
}
Hello, Alice!

By providing a more intuitive and flexible way to work with member functions, std::mem_fn() leads to code that is not only more readable but also more maintainable and less prone to errors related to the complexities of raw member function pointers.

Answers to questions are automatically generated and may not have been reviewed.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 55 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved