Using std::mem_fn()
can significantly improve code readability compared to raw function pointers in several ways:
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);
}
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)
);
}
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.
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
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.
Explore advanced techniques for working with class member functions