mardi 4 juillet 2017

How does automatic function template type deduction work with variadic templates?

I'm trying to write a function template that takes a callback (as an std::function) and it's arguments and calls the callback with it's arguments.

Currently, it works only with a lot of explicit casting and conversions, while I want it to work as simple as a direct call to the function.

#include <iostream>
#include <functional>
#include <string>
#include <utility>

template<typename... Args>
static void do_callback(std::function<void(Args...)> callback,
    Args&& ...args)
{
    callback(std::forward<Args>(args)...);
}

static void f(std::string const &s, int &n)
{
    std::cout << __func__ << ", " << s << ", " << ++n << std::endl;
}

int main()
{
    int n = 0;

    f("Hello f!", n);

    // how it should work - fails ("mismatched types
    // ‘std::function<void(Args ...)>’ and
    // ‘void (*)(const string&, const int&)
    // {aka void (*)(const std::__cxx11::basic_string<char>&,
    // const int&)}’"

    do_callback(f, "Hello do_callback!", n);

    // workaround - really ugly (explicit casting)

    do_callback(
        std::function<decltype(f)>{f},
        static_cast<std::string const &>("Hello workaround!"),
        n
    );
}

(g++ 5.4.0 with -std=c++11)

Aucun commentaire:

Enregistrer un commentaire