fork(1) download
  1. #include <iostream>
  2. #include <tuple>
  3. #include <cassert>
  4. #include <functional>
  5. using namespace std;
  6.  
  7. struct invoke_fn
  8. {
  9. template <typename F, typename ... As>
  10. constexpr decltype(auto) operator () (F && f, As && ... as) const
  11. {
  12. return std::forward<F>(f)(std::forward<As>(as)...);
  13. }
  14. };
  15. constexpr auto invoke = invoke_fn{};
  16.  
  17. template <class F, class Tuple, std::size_t... I>
  18. constexpr decltype(auto) apply_impl( F&& f, Tuple&& t, std::index_sequence<I...> )
  19. {
  20. return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
  21. }
  22.  
  23. template <class F, class Tuple>
  24. constexpr decltype(auto) apply(F&& f, Tuple&& t)
  25. {
  26. return apply_impl(std::forward<F>(f), std::forward<Tuple>(t),
  27. std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{});
  28. }
  29.  
  30. struct forward_as_tuple_fn
  31. {
  32. template <typename ... Ts>
  33. constexpr decltype(auto) operator () (Ts && ... ts) const
  34. {
  35. return std::forward_as_tuple(std::forward<Ts>(ts)...);
  36. }
  37. };
  38.  
  39. constexpr auto forward_as_tuple1 = forward_as_tuple_fn{};
  40.  
  41. template <typename T>
  42. constexpr decltype(auto) forward_tuple (T && t)
  43. {
  44. return apply(forward_as_tuple1, std::forward<T>(t));
  45. }
  46.  
  47. template<typename ...As>
  48. constexpr decltype(auto) part(As && ...as)
  49. {
  50. return [as = std::make_tuple(std::forward<As>(as)...)](auto && ...as2)
  51. {
  52. return apply(invoke, std::tuple_cat(forward_tuple(as), std::forward_as_tuple(as2...)));
  53. };
  54. }
  55.  
  56.  
  57. struct Caller
  58. {
  59. Caller() = default;
  60. Caller(const Caller&) { std::cout << "copy" << std::endl; }
  61. Caller(Caller&&) { std::cout << "move" << std::endl; }
  62.  
  63. template <typename T>
  64. auto operator () (T t) const
  65. {
  66.  
  67. }
  68. };
  69.  
  70.  
  71. int main()
  72. {
  73. auto c = Caller();
  74. // только одно копирование, при создание объекта part, при создание кортежа.
  75. part(c)(3.14);
  76. return 0;
  77. }
Success #stdin #stdout 0s 3468KB
stdin
Standard input is empty
stdout
copy