我们用最简单的方式完成它的功能,即requires和lambda,只需要三个函数重载即可
源码如下:
template<class ...Args,class F>requires std::is_pointer_v<F>
inline auto bind(F f, Args&&...args) {
return [=]()mutable
{
return f(std::forward<Args>(args)...);
};
}
template<class ...Args, class F>requires std::is_class_v<F>
inline auto bind(F f, Args&&...args) {
return [=]()mutable
{
return f(std::forward<Args>(args)...);
};
}
template<class...Args, class T, class A>requires (!std::is_class_v<A> && !std::is_pointer_v<A>)
inline auto bind(A func, T f, Args...args) {
return [=]()mutable
{
return (f->*func)(std::forward<Args>(args)...);
};
}
分别对应处理函数指针,函数对象,成员函数
这里使用到了:template 形参包,包展开,完美转发,类型萃取,概念
单元测试如下:
struct Test_bind {
void t(int n) {
for (; n; n--)
std::cout << "t\n";
}
void operator()(int n) {
std::cout << n << '\n';
}
};
void Test_bind() {
std::function F = ff;
auto p = my::bind(F, 1);
p();
std::function F2 = p;
F2();
auto p2 = my::bind(ff, 10);
p2();
std::function F3 = p2;
F3();
//可以传递带捕获的lambda
auto p3 = my::bind([=](int v) {return ff(v); }, 10);
p3();
std::function F4 = p3;
F4();
Test_bind t_b;
auto p4 = my::bind(&Test_bind::t, &t_b, 2);
p4();
std::function F5 = p4;
F5();
auto p5 = my::bind(Test_bind(), 2);
p5();
std::function F6 = p5;
F6();
}
注意,您的编译器需要支持到c++20,同时我们实现的bind并不支持占位符
在visual studio 2022通过编译
如果还想要STL的其他实现,可以看本人GitHub
GitHub - 13870517674/c-plus-plus: wawuwawu. Contribute to 13870517674/c-plus-plus development by creating an account on GitHub.https://github.com/13870517674/c-plus-plus如vector,span,array,string_view,以及一些C++20模块的使用和其他三方库的例子,如xlnt