jeudi 25 mars 2021

C++ template function pointer type deduction

I have the following code

using my_map_t = std::map<int, Object<double>>;
using my_map_iterator_t = my_map_t::iterator;


template <typename FWD, typename Func>
void inner(my_map_t& map, int key, FWD&& obj, Func emplacer) {
        emplacer(map, key, std::forward<FWD>(obj));
}
  

my_map_t map;

template <typename FWD>
void outer(my_map_t& map, int key, FWD&& obj)
{
        auto lambda = [](my_map_t& m, int k, FWD&& o) {
                m.emplace(k, std::forward<FWD>(o));
        };

        inner(map, key, std::forward<FWD>(obj), lambda);
}

which compiles painlessly. So this means that he deduce automatically the template argument of inner function. However, if I introduce a function pointer I need to specify the function pointer template argument, otherwise the compiler complaints

using my_map_t = std::map<int, Object<double>>;
using my_map_iterator_t = my_map_t::iterator;


template <typename FWD, typename Func>
void inner(my_map_t& map, int key, FWD&& obj, Func emplacer) {
        emplacer(map, key, std::forward<FWD>(obj));
}

template <typename FWD, typename Func>
void(*fp)(my_map_t&, int, FWD&&, Func) = &inner;


my_map_t map;

template <typename FWD>
void outer(my_map_t& map, int key, FWD&& obj)
{
        auto lambda = [](my_map_t& m, int k, FWD&& o) {
                m.emplace(k, std::forward<FWD>(o));
        };

        (*fp<FWD, decltype(lambda)>)(map, key, std::forward<FWD>(obj), lambda);
}

Why in the case of function pointer the argument deduction is not working any more? Did I make some mistake? Is there a way to achieve a better syntax?

NOTE ADDED

I need to use function pointer because I have some function with the same signature of inner. Let us call them inner1, inner2 and inner3. They are called by some outer function

void outer(...) {
     if(...) {

         inner1(...)
     } else if (...) {
     
         inner2(...)
     } else {

         inner3(...)
     }
     some_long_task(...)
}

Now in my case the outer function is called cyclically. The checks in the ifs can be time consuming and they are independent of the argument of outer function. I was thinking while the some_long_task is being executed, to set up a function pointer to the right function inner1, inner2 or inner3 exploiting some cpu parallelism, so that, the the new cycle begin, I do not have to waste time doing the if check.

Aucun commentaire:

Enregistrer un commentaire