Created
October 1, 2022 09:34
-
-
Save BlurryLight/17c99bb9d6e02dab2f4865b5204d24a3 to your computer and use it in GitHub Desktop.
naive bind c++17
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://godbolt.org/z/7hefs586j | |
#include <functional> | |
#include <tuple> | |
#include <iostream> | |
template <size_t n> using index_constant = std::integral_constant<size_t, n>; | |
template<class ... Args> | |
class callee_list | |
{ | |
public: | |
template<class ... TArgs> | |
constexpr callee_list(TArgs&&... args) noexcept | |
: boundedArgs_{std::forward<TArgs>(args)...} | |
{} | |
template<class T> | |
constexpr decltype(auto) operator[](T&& t) noexcept | |
{ | |
if constexpr (!std::is_placeholder_v<std::decay_t<T>>) | |
{ | |
return std::forward<T>(t); | |
} | |
else | |
{ | |
constexpr size_t Index = std::is_placeholder<std::decay_t<T>>::value - 1; | |
return std::get<Index>(std::move(boundedArgs_)); | |
} | |
} | |
// Bind以值类型存储所有变量,会擦除int& 到int | |
std::tuple<typename std::decay_t<Args>...> boundedArgs_; | |
}; | |
template<class Fn, class ... Args> | |
class binder | |
{ | |
public: | |
template<class TFn, class ... TArgs> | |
constexpr binder(TFn&& f, TArgs&&... args) noexcept | |
: f_{std::forward<TFn>(f)}, | |
UnresolvedArgsList_{std::forward<TArgs>(args)...} | |
{} | |
template<class ... CallArgs> | |
constexpr decltype(auto) operator()(CallArgs&&... args) | |
{ | |
return call(std::make_index_sequence<sizeof...(Args)>{}, std::forward<CallArgs>(args)...); | |
} | |
private: | |
template<class ... CallArgs, size_t ... Seq> | |
constexpr decltype(auto) call(std::index_sequence<Seq...>, CallArgs&&... args) | |
{ | |
// 创建callee_List保存调用Operator()时候传入的参数,用于补齐占位符 | |
auto calleeList = callee_list<CallArgs...>{std::forward<CallArgs>(args)...}; | |
// 调用callee_list.operator[] | |
// Redchards原版: | |
// 参数折叠展开 f_(calleeList[argumentList_[index_constant<0>{}]],calleeList[argumentList_[index_constant<1>{}]],...); | |
return f_(calleeList[std::get<index_constant<Seq>{}>(UnresolvedArgsList_)]...); | |
} | |
private: | |
std::function<std::remove_reference_t<std::remove_pointer_t<Fn>>> f_; | |
// 将占位符以及原有的参数保存在UnResolvedArgsLists_里,在call的时候填充占位符 | |
std::tuple<typename std::decay_t<Args>...> UnresolvedArgsList_; | |
}; | |
template<class Fn, class ... Args> | |
// The code is from RedChards https://gist.github.com/Redchards/c5be14c2998f1ca1d757 | |
binder<Fn, Args...> Redchards_Bind(Fn&& f, Args&&... args) | |
{ | |
return binder<Fn, Args...>{std::forward<Fn>(f), std::forward<Args>(args)...}; | |
} | |
int foobar(int a,int& b) | |
{ | |
std::cout << "a: " << a << std::endl; | |
return ++b; | |
} | |
int main() | |
{ | |
std::cout << "naive bind " << std::endl; | |
int n = 0; | |
int& n_ref = n; | |
auto fn = Redchards_Bind(foobar,1,n_ref); | |
// bind的引用捕获不能修改外部变量,内部复制了一个值 | |
std::cout << fn() << " " << n << std::endl; | |
std::cout << fn() << " " << n << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
code is modified from https://gist.github.com/Redchards/c5be14c2998f1ca1d757 by Redchards