So I have a ton of functions similar to these:
template <typename T>
bool Zero(const T, const T, const T);
template <typename T>
T One(const T, const T, const T, bool);
template <typename T>
T Three(const T, const T, const T, const T, const T, const T);
For each of these functions I have a wrapper which uses the return type of these functions so it looks something like this:
template <typename T>
decltype(Zero<decltype(declval<T>().x)>(decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()))) ZeroWrapper(const T);
template <typename T>
decltype(One<decltype(declval<T>().x)>(decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), bool())) OneWrapper(const T);
template <typename T>
decltype(Three<decltype(declval<T>().x)>(decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()))) ThreeWrapper(const T);
As you can see all those decltype(declval<T>().x)
's get disgustingly hard to read. Can I template a using
or is there some standard function which will allow me to extract the return type from a function pointer without passing the argument types to decltype
or result_of
? So something like this:
template <typename T>
foo_t<Zero<decltype(declval<T>().x)>> ZeroWrapper(const T);
template <typename T>
foo_t<One<decltype(declval<T>().x)>> OneWrapper(const T);
template <typename T>
foo_t<Three<decltype(declval<T>().x)>> ThreeWrapper(const T);
In c++17 the function
object has been endowed with a Deduction Guide which allows it to determine it's type from the argument passed to the constructor. So for example, given the function int foo()
in c++11 we had to do:
function<int()> bar(foo);
In c++17 bar
's function<int()>
type will be derived if we simply:
function bar(foo);
Thus we can use the Deduction Guide to populate a temporary function
with only the signature; thereby using function
's result_type
to find the result of your helper funcitons:
template <typename T>
typename decltype(function(Zero<decltype(declval<T>().x)>))::return_type ZeroWrapper(const T);
template <typename T>
typename decltype(function(One<decltype(declval<T>().x)>))::return_type OneWrapper(const T);
template <typename T>
typename decltype(function(Three<decltype(declval<T>().x)>))::return_type ThreeWrapper(const T);