Let's consider:
void goo () {
std::cout << "void goo ()\n";
}
int goo (int) {
std::cout << "int goo (int)\n";
return 42;
}
And now I want to call one of those functions using some wrapper function defined like this:
template <typename F, typename... A>
void c (F&& f, A&&... a) {
f (std::forward<A> (a)...);
}
With usage:
c (&goo, 10); // (X)
c (&goo); // (Y)
Both cases fail (GCC 5.3.1) with appropriate errors:
error: no matching function for call to ‘c(<unresolved overloaded function type>, int)’
error: no matching function for call to ‘c(<unresolved overloaded function type>)’
As far as I am concerned the fail is because compiler could not choose appropriate overload when it has to initialize f
object (too few information).
As a solution of course I can write usage calls like this:
c (static_cast<int (*) (int)> (&goo), 10);
c (static_cast<void (*) ()> (&goo));
To tell the compiler which pointer I really want to use.
Writing this static_cast
for me makes code much more uglier, so I wrote a wrapper function for converting function pointer to appropriate one using template:
template <typename R, typename... Args>
using Funptr_t = R (*) (Args...);
template <typename R, typename... Args>
Funptr_t<R, Args...> funptr (Funptr_t<R, Args...> ptr) {
return static_cast<Funptr_t<R, Args...>> (ptr);
}
and now usage looks much better:
c (funptr<int, int> (&goo), 10);
c (funptr<void> (&goo));
My question is: Do you have any better idea how to deal with that kind of situation? I am pretty sure this happen very often in generic code. So, please advice me something.
The ideal solution would be if I could use (X) and (Y) directly, so the magic trick with pointing appropriate overload would be done using A...
and hidden to the caller.
Aucun commentaire:
Enregistrer un commentaire