How do I store a vector of std::bind without a specific case for the template?

3.7k views Asked by At

After going though a question on std::bind, I was wondering if it was possible to hold a vector of functions created by std::bind so I can avoid using std::function and its heavyweight wrapping.

#include <iostream>
#include <functional>
#include <typeinfo>
#include <vector>

int add(int a, int b) {return a + b;}

int main() {

    //I believe this here is just a special type of bound function.
    auto add2 = std::bind(add, std::placeholders::_1, 2);
    auto add3 = std::bind(add, std::placeholders::_1, 3);

    //Yup.
    std::cout << typeid(add2).name() << std::endl;
    //Here's the type of the second function
    std::cout << typeid(add3).name() << std::endl;

    //Is there a nicer way to do this?
    std::vector<decltype(std::bind(add, std::placeholders::_1, 1))> vec;

    return 0;   
}

Although it's possible of to create a vector of std::bind functions, is there a way I don't have to provide a specific case of a bound function in order to declare a container without an empty/dummy type of a function made from std::bind?

2

There are 2 answers

0
CinchBlue On BEST ANSWER

So, it appears that this isn't possible--std::bind doesn't appear to have a normally nameable/explicit type--the type is usually generated according to the signature of the bound function, and doesn't appear to be specifiable. Using std::function seems to be the only way to wrap std::bind functions and store them in a vector.

Even for lambdas, this doesn't seem possible--using a wrapper in the form of std::function seems to be the go-to answer, despite the increased size of the resulting function-object.

Possible alternatives might be storing Functor objects designed to mimic closures couples with generic objects with a type-checking layer (though this seems quite heavy). Whatever the case, using std::function seems to be the cleanest solution.

3
SU3 On

How about this?

#include <iostream>
#include <functional>
#include <vector>

int add(int a, int b) { return a + b; }

using bound_add_t = decltype(std::bind(add, std::placeholders::_1, int()));

int main() {
  std::vector<bound_add_t> vec;
  vec.emplace_back(add,std::placeholders::_1, 1);
  vec.emplace_back(add,std::placeholders::_1, 2);
  vec.emplace_back(add,std::placeholders::_1, 3);

  for (auto &b : vec)
    std::cout << b(5) << std::endl;

  return 0;   
}