如何使用std::bind绑定带enable_if的成员函数?
问题解决:std::bind绑定enable_if启用的模板成员函数
问题根源
test<int>::foo是模板成员函数,且存在两个基于enable_if的重载版本。当尝试用&test<int>::foo获取函数地址时,编译器无法自动推导模板参数U(即便它有默认值T),也就无法确定要绑定哪一个重载实例,最终导致编译失败。
解决办法
1. 显式指定模板参数
直接在取函数地址时明确指定U的类型,让编译器定位到具体的函数实例:
auto func = std::bind(&test<int>::foo<int>, &myfoo, 3); // 显式指定U=int
2. 用Lambda替代std::bind(更推荐)
Lambda表达式可以直接捕获对象并调用成员函数,完全绕开函数模板地址的推导问题,代码更简洁直观:
auto func = [&myfoo]() { myfoo.foo(3); };
3. 重构函数消除重载(你已采用的if constexpr方案)
将两个重载的foo合并为一个,用if constexpr在编译时处理分支逻辑,这样foo不再是重载的模板函数,bind时自然不会有歧义:
template <typename U = T> void foo(const T& v){ if constexpr(std::is_copy_constructible_v<U>){ std::cout << "copy constructible"; } else { std::cout << "not copy constructible"; } }
补充说明
直接调用myfoo.foo(3)能成功,是因为编译器可以通过调用上下文推导出模板参数U的默认值,进而匹配对应的重载。但取函数地址时没有这样的推导上下文,必须显式指定模板参数,或者用Lambda这种更灵活的方式替代bind。
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

