C++ 获取模板参数的 return 类型

C++ get return type for template argument

我有

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;
};

如何为 DistanceTypeDistanceFunc 导出 return 类型?

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

视情况而定。如何调用 DistanceFunc 类型的函数?

假设使用 int 调用,您可以尝试使用

using DistanceType = decltype(std::declval<DistanceFunc>()(std::declval<int>()));

如果您有从 DistanceFunc 收到的类型,使用 decltype()std::declval() 您可以模拟对函数的调用并获得结果类型。

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

另一个解决方案是使用模板专业化。

您可以将 C 声明为接收 typename,而无需对其进行定义

template <typename>
class C;

然后你可以定义一个 C 的特化来接收一个(指向)函数类型,如下所示

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;
};

如您所见,函数类型被解析为 return 类型和参数类型。现在 DistanceType 只是推导(作为 return 类型),您必须重新创建 DistanceFunc.

您可以如下使用

int foo (int, long)
 { return 0; }

// ...

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

从C++17开始还可以添加推导指南

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

因此您可以简单地声明一个 C 对象

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