std::bind1st和std::bind2nd在C++11弃用、C++17移除,因依赖已淘汰的std::unary_function等基类且要求函数对象显式定义argument_type等typedef,而lambda、普通函数等均不满足;应改用std::bind配合_1/_2占位符或更优的lambda表达式。

std::bind1st 和 std::bind2nd 在 C++11 起已被弃用,C++17 正式移除,不能再用。 它们依赖 std::unary_function 和 std::binary_function 等过时基类,且仅支持继承自这些基类的仿函数——现代 lambda、普通函数指针、重载了 operator() 的类都不满足条件,一用就编译失败。
为什么 std::bind1st/bind2nd 编译不过
常见报错类似:no type named 'argument_type' in 'struct XXX' 或 no matching function for call to 'bind1st'。根本原因是:这些适配器要求传入的函数对象必须显式定义 argument_type、result_type 等 typedef,而 lambda 表达式、自由函数、甚至多数 functor 都不提供这些——它们不是为这套老机制设计的。
- lambda(如
[] (int, int) { return ...; })没有argument_type -
std::plus等标准函子在 C++11 后也移除了这些 typedef - 即使手写 functor,漏定义
first_argument_type也会触发错误
直接替换:用 std::bind + _1 / _2 占位符
std::bind 是通用、类型安全的替代方案,不依赖任何基类,能包装任意可调用对象。绑定位置由占位符 _1、_2 显式指定,语义更清晰。
-
std::bind1st(f, x)→std::bind(f, x, _1) -
std::bind2nd(f, y)→std::bind(f, _1, y) - 需包含头文件:
,并引入命名空间:using namespace std::placeholders; - 示例:
auto f = std::bind(std::minus(), _1, 5); f(10); // 返回 5
更推荐:直接用 lambda 表达式
绝大多数场景下,lambda 比 std::bind 更直观、性能更好(无类型擦除开销),且无需记占位符规则。
立即学习“C++免费学习笔记(深入)”;
-
std::bind1st(std::less→(), 3) [](int x) { return 3 -
std::bind2nd(std::multiplies→(), 2.5) [](double x) { return x * 2.5; } - 捕获变量也更自然:
[&val](int x) { return x + val; },不用绕一圈std::bind捕获
真正需要兼容旧代码时才查 std::bind 占位符规则;日常开发中,看到 bind1st/bind2nd 就该条件反射替换成 lambda——它不光能跑,还更容易读、更容易改、更容易调试。









