Ælex
Ælex

Reputation: 14839

getting template type from lambda auto

I'm in a bit of a pickle, following up my previous question and using a code similar to the one I posted here.

  1. I use a variadic template function which accepts variadic objects
  2. It packs them into a tuple
  3. Iterates them using the visitor idiom
  4. Binds for each object a callback

Instead of the original minified example shown below:

template <typename... Args>
void make_classes(Args... args)
{
    auto t = std::tuple<Args...>(args...);
    unsigned int size = std::tuple_size<decltype(t)>::value;
    auto execute = [](auto & obj){ obj.operator()(); };

    for (int i = 0; i < size; i++) {
        visit_at(t, i, execute);
    }
}

I am trying to understand how I can deduce the template type of the auto lambda, so that I can bind it:

template <typename... Args>
void make_classes(Args... args)
{
    auto t = std::tuple<Args...>(args...);
    unsigned int size = std::tuple_size<decltype(t)>::value;
    auto execute = [](auto & obj){ 
        // obtain type of obj as T?
        auto callback = std::bind(&T::deserialise, obj, std::placeholders::_1);
        // do something else here using this callback.
    };

    for (int i = 0; i < size; i++) {
        visit_at(t, i, execute);
    }
}

There's a catch: the parameter objects are non-copyable (although I could change that), but I would like to know if/how the above could work by deducing the template type packed in the tuple as obtained by the visitor.

If I can't deduce the type inside the lambda, can I somehow store it within the tuple (e.g.,: type & object) in order to later extract it?

Upvotes: 1

Views: 279

Answers (1)

Barry
Barry

Reputation: 302942

Just use another lambda:

auto callback = [&obj](auto& x){
    obj.deserialise(x);
};

std::bind is rarely useful. (If you really want to copy obj, you can drop the leading &.)


Moreover, you don't actually need a tuple...

template <class F, class... Args>
void for_each_arg(F&& f, Args&&... args) {
    using swallow = int[];
    (void)swallow{0,
        (void(f(std::forward<Args>(args))), 0)...
    };
}

template <typename... Args>
void make_classes(Args... args)
{
    for_each_arg([](auto& obj){
        auto callback = [&obj](auto& x) { obj.deserialise(x); };
        // do something with callback
    }, args...);
}

Upvotes: 6

Related Questions