I want to constraint a template parameter depending on the functor passed. Consider this FoldLeft
function, from some container type:
template<typename F, typename R>
R FoldLeft(F&& functor, R initialValue) {
R r = initialValue;
/* assume that this is a range of uint64_t's */
while (first != last) {
r = std::forward<F>(functor)(r, *(first++));
}
return r;
}
This function can be called like this:
auto sum = FoldLeft([](uint64_t i, auto& e) { return e + i; }, 0);
Here, the problem is that R
is deduced from the initialValue
parameter, which is 0
in this case and thus leads to int
. Similarly decltype(sum)
also gives int
.
I want to have R
deduced as the return type of the functor, which may be a lambda or any other callable type. I already tried using the method from this answer, but always run into this error:
error: decltype cannot resolve address of overloaded function
struct function_traits
^~~~~~~~~~~~~~~
note: substitution of deduced template arguments resulted in errors seen above
The code for my attempt (fuction_traits
copied from the linked answer):
template<typename T>
using LamRet = typename function_traits<T>::result_type;
template<typename F>
LamRet<F> FoldLeft(F&& functor, LamRet<F> initialValue) {
LamRet<F> r = initialValue;
/* assume that this is a range of uint64_t's */
while (first != last) {
r = std::forward<F>(functor)(r, *(first++));
}
return r;
}