С точки зрения assembly при включённой оптимизации (-O2)
std::mem_fn и эквивалентная лямбда дают идентичный код. Оба являются callable с inline-дружественной структурой: компилятор видит конкретный тип и инлайнит вызов.🍿 Разница появляется в контексте стирания типов
Если callable хранится в
std::function<>:// Лямбда — захват this в замыкании
std::function<int(Foo&)> f1 = [](Foo& x) { return x.bar(); };
// mem_fn — хранит pointer-to-member
std::function<int(Foo&)> f2 = std::mem_fn(&Foo::bar);
❗️ В обоих случаях std::function выполняет type erasure — heap-аллокацию для хранения callable (если он не влезает в Small Buffer Optimization, обычно ≤16 байт). Для mem_fn размер объекта — ровно размер pointer-to-member (8-16 байт), для лямбды без захвата — 1 байт. Оба влезают в SBO.
💡 Реальная разница — читаемость и семантика.
std::mem_fn явно сигнализирует «это вызов метода». Лямбда гибче, но многословнее. В алгоритмах с однотипными вызовами mem_fn лаконичнее:std::transform(v.begin(), v.end(), out.begin(), std::mem_fn(&Widget::value)); // vs лямбда
✏️ Используй mem_fn, когда хочешь выразить «вызов конкретного метода». Лямбду — когда нужна логика внутри.
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#под_капотом