模板函数的部分类型定义(`using`)

Partial typedef (`using`) of a templated function

尝试使用模板实现点积函数,我编写了以下模板函数。

template <typename T, typename R = float,
  typename = 
    std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().x)>{}>,
  typename = 
    std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().y)>{}>>
constexpr R dot(const T a_vector, const T b_vector)
{
    return a_vector.x * b_vector.x + a_vector.y * b_vector.y;
}

我希望我的用户也能轻松使用 dot 函数返回 double 而不是默认值 float。这就是为什么我使用 using 到 "typedef" dot().

template<typename T, typename R, typename ... >
using dotd = dot<T, double>;

此代码产生

我可以选择使用替代函数吗?

答案很简单:

template <class T1, class T2> void foo();

template <class T1, class T2> struct FooHelper {
   static constexpr auto foo = &foo<T1, T2>;
};

template <class T>
auto food = FooHelper<T, float>::foo;

void g() {
  food<float>();
}

您可以翻转模板参数的顺序。如果将 R 放在首位,用户可以轻松地为其提供不同的类型(如果这是他们想要的):

template <
  typename R = float,
  typename T,
  typename = 
    std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().x)>{}>,
  typename = 
    std::enable_if_t<std::is_arithmetic<decltype(std::declval<T>().y)>{}>>
constexpr R dot(const T a_vector, const T b_vector)
{
    return a_vector.x * b_vector.x + a_vector.y * b_vector.y;
}

然后 dot(a, b) 给你一个 floatdot<double>(a, b) 给你一个 double。我发现 dot<double> 比必须查找 dotd 的含义要清楚得多。

尽管如果您使用的是 C++14,最好完全删除 R 模板参数和 return auto