3

I'm trying to implement something like std::bind() from scratch. Over in How does std::bind take variadic arguments by value, even with its universal reference? I asked how it would be possible to store variadic arguments in a tuple by value, while using perfect forwarding. I learned about std::decay_t<T> which lets me do just this. I have a partial implementation of my Bind() function in http://coliru.stacked-crooked.com/a/2655a48fe82f0d4c which you can see.

I can't seem to apply a function on the unpacked arguments however, if any of the arguments are move-only. I think this is really useful behavior but I can't quite figure out how to achieve it. The easiest way to apply a function to a tuple of variadic arguments would be to simply call std::apply(f_, args_);, as my example does, however this of course breaks with move-only args.

So I attempted to use an std::index_sequence and another method InvokeImpl to accept the moved tuple and the variadic index sequence -- it ony-by-one unpacks the arguments and forwards them to be invoked by the functor. This actually works for move-only types, but fails for types passed by value or std::ref(), which is of course now what I'm looking for. Is there a way to get this to work for all kinds of types?

Dominic Farolino
  • 1,362
  • 1
  • 20
  • 40
  • `std::bind` does not work very well with move-only types, see [std::bind and rvalue reference](https://stackoverflow.com/questions/34877699/stdbind-and-rvalue-reference). My advice would be to forget `std::bind` exists and use lambdas. – Quimby Sep 06 '21 at 20:34
  • Hah, well honestly I'm trying to make a better std::bind(), and while I'm not opposed to using lambdas, I really feel compelled to get this right for my own learning. Chromium has a BindOnce [1] that works perfectly for move-only types and I'd love to learn how to make something similar [1]: https://source.chromium.org/chromium/chromium/src/+/main:base/bind.h;l=62;drc=ea615d420d733796f4c1ee83bdcb8788d55232da – Dominic Farolino Sep 06 '21 at 21:01
  • Not to mention, I'd like to store the resulting functor somewhere, and it can't be a std::function if I am to use move-only types, which means I'm going to have to build something like bind() anyways to give me an object that I can store, I believe. – Dominic Farolino Sep 06 '21 at 21:07
  • Okay, I think I understand now, sorry "chasing you away", nothing wrong with trying to make better `std::bind` for learning purpose. I will post my attempt shortly. – Quimby Sep 07 '21 at 07:04
  • 1
    Also please post the code here, it is strongly preferred making the questions self-contained. – Quimby Sep 07 '21 at 07:10
  • On a second though I think there is a problem with your approach. What is the desired behaviour for `foo(int&, unique_ptr&)`, `foo(int, unique_ptr)` for arguments capture by value and by reference. I mean if `int` is captured by value, should it be copied or moved into the second `foo`? Seems that you want different behaviour based on `foo`'s signature, that is very hard AFAIK to achieve. – Quimby Sep 07 '21 at 07:34

0 Answers0