c++templatestype-deductionreturn-type-deduction

C++ get return type for template argument


I have

template<typename DistanceFunc>
class C
{
    using DistanceType = // the return type from DistanceFunc

public:
    C(DistanceType distance, DistanceFunc f)
    : m_distance(distance),
      m_f(f)
    {}

private:
    DistanceType m_distance;
    DistanceFunc m_f;
};

How do I derive the return type from DistanceFunc for DistanceType?


Solution

  • How do I derive the return type from DistanceFunc for DistanceType?

    Another solution could be use template specialization.

    You can declare C as receiving a typename, without defining it

    template <typename>
    class C;
    

    Then you can define a specialization of C receiving a (pointer to) function type as follows

    template <typename DistanceType, typename ... Args>
    class C<DistanceType(*)(Args...)>
     {
       using DistanceFunc = DistanceType(*)(Args...);
    
    public:
        C(DistanceType distance, DistanceFunc f)
        : m_distance(distance), m_f(f)
        {}
    
    private:
        DistanceType m_distance;
        DistanceFunc m_f;
    };
    

    As you can see the function type is resolved as a return type and the types of the arguments. Now DistanceType is simply deduced (as return type) and you have to recreate DistanceFunc.

    You can use it as follows

    int foo (int, long)
     { return 0; }
    
    // ...
    
    C<decltype(&foo)> c0{0, &foo};
    

    Starting from C++17 you can also add a deduction guide

    template <typename DistanceType, typename ... Args>
    C(DistanceType, DistanceType(*)(Args...)) -> C<DistanceType(*)(Args...)>;
    

    so you can declare a C object simply as

    C c0{0, &foo}; // C<decltype(&foo)> is deduced