Search code examples
c++templatesc++20return-typedecltype

How to get return type of template parameter method?


I am trying to make a template class that expects a lambda as input, stores it, and also stores in a vector some elements of type = return type of the lambda. But I don't know how to get that type, even though when an instance is built the lambda is known with also its return type.

I'd like the class to be constructed without giving template parameters (like std::array a{1, 2, 3}). I tried with decltype(F::operator(double x)) but it doesn't work.

#include <vector>

template<typename F>
struct Foo {
    using value_t = decltype(F::operator(double x))// <--- here I need to get the return type of the 
                                                 // call operator of F!
    Foo(const F& f) : _f(f), _vals(10, value_t{}), _has_vals(10, false) {}
    
    value_t operator()(int i) {
        if (_has_vals[i])
            return _vals[i];
        else {
            _has_vals[i] = true;
            _vals[i] = _f(i);
        }
    }
    
    F _f;
    std::vector<value_t> _vals;
    std::vector<bool> _has_vals;
};
#include <iostream>    

int main() {
    Foo foo([](double x){ return 42; }); // <--- here I know that the lambda returns an int!
    std::cout << foo(3) << "\n";
    return 0;
};

Solution

  • decltype needs an actual call expression to get the return type, which you can't really reliably get from the type F (because the type F might not be default-constructible for example).

    You must use std::declval to "create" an instance of F that you can then call.

    Perhaps something like

    using value_t = decltype(declval<F>()(0.0));