Search code examples
c++templatestype-traitsdecltype

C++ template result_of_t no type named 'type' when trying to find return value of function


I'm trying to get the return type of a function template. One solution I saw uses result_of_t:

#include <iostream>
#include <vector>
#include <string>
#include <type_traits>
#include <map>
#include <unordered_map>
#include <any>
using namespace std;

using MapAny = map<string, any>;

template <typename num_t>
num_t func1_internal(const vector<num_t> &x, int multiplier) {
    num_t res = 0;
    for (int i=0; i<x.size(); i++)
        res += multiplier * x[i];
    return res;
}
template <typename num_t>
class Func1 {
using ResultType = num_t; // std::result_of_t<decltype(func1_internal<num_t>)>;
//using ResultType = std::result_of_t<decltype(func1_internal(const vector<num_t>&, int))>;
private:
    vector<int> multipliers;

public:
    Func1(const vector<MapAny> &params) {
        for (const auto& param : params) {
            multipliers.push_back(any_cast<int>(param.at("multiplier")));
        }
    }

    any operator()(const vector<double> &x) {
        vector<ResultType> res;
        for (int multiplier : multipliers)
            res.push_back(func1_internal(x, multiplier));
        return res;
    }
};

int main()
{
    Func1<float> func1({});
    return 0;
}

However, it gives me an error:

/usr/include/c++/10/type_traits: In substitution of ‘template<class _Tp> using result_of_t = typename std::result_of::type [with _Tp = float(const std::vector<float, std::allocator<float> >&, int)]’:
fobject.cpp:21:7:   required from ‘class Func1<float>’
fobject.cpp:45:23:   required from here
/usr/include/c++/10/type_traits:2570:11: error: no type named ‘type’ in ‘class std::result_of<float(const std::vector<float, std::allocator<float> >&, int)>’
 2570 |     using result_of_t = typename result_of<_Tp>::type;

What's the correct way to do this in C++20? Also, I heard that std::result_of is deprecated, so I'm looking for the best way possible.


Solution

  • You can use C++17 std::invoke_result, where the first argument is the callable type, followed by arguments type

    using ResultType = invoke_result_t<
      decltype(func1_internal<num_t>), const vector<num_t>&, int>;
    

    decltype(func1_internal<num_t>) will get the function type of int(const std::vector<int>&, int).