I was experimenting with overloads
int foo(int,int);
int foo(int);
int main() {
//decltype(foo) x; // error: reference to overloaded function could not be resolved;
decltype(foo(1)) f;
}
I know that I cannot get a pointer to foo
unless I pick one of the overloads, but I wonder why do overload sets have no type? Wouldnt it be natural to write
template <typename F>
void foofoo(F f,bool x) {
if (x) f(1);
else f(1,0);
}
and call it as foofoo(foo,true);
? I know that there are different ways to write something like that, but I specifically wonder about overload sets. Anyhow, my question is
Is there anything I can do with an overload set before picking one of the overloads?
In other words, is there some magic
that would make the following true
literally as is?
std::is_same_v< decltype( foo(1,1) ), magic<foo,int,int>::type >;
Or is this generally not possible, because foo
is unresolved?
There are very few things you can do with the name of an overloaded function set that don't immediately require resolving to one specific function (or function template specialization). But one context where many semantic checks get "delayed" in a way is inside a template. And a generic lambda is a shortcut way of writing a template. So one thing we can do is:
#include <utility>
#define WRAP_OVERLOADS(f) [](auto&& ...args) { \
return f(std::forward<decltype(args)>(args)...); }
int foo(int, int);
int foo(int);
int main() {
auto f = WRAP_OVERLOADS(foo);
f(1);
f(2,3);
}
Though the preprocessor #define
is required because there's no way to represent the name of the function to call to pass to a template. (A function pointer can be a template argument or can help deduce the type of a template function parameter, but then you're back to needing one specific overload to use the template.)