std::mem_fn()
and Code Readability
How does using std::mem_fn()
improve code readability compared to raw function pointers?
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.
Member Function Pointers and Binding
Explore advanced techniques for working with class member functions