模板化函数的部分typedef(`using`)

时间:2016-02-24 20:30:19

标签: c++ templates typedef c++14 using

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

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

此代码产生

  • in g ++ error: ‘dot<T, float>’ does not name a type
  • in clang ++ error: expected a type error: expected ';' after alias declaration

我是否可以选择使用替代功能?

2 个答案:

答案 0 :(得分:3)

你可以翻转模板参数的顺序。如果您先放置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)为您提供float vs dot<double>(a, b)给您一个double。我发现dot<double>比查找dotd的含义要清楚得多。

虽然如果你正在使用C ++ 14,最好简单地完全删除R模板参数并返回auto

答案 1 :(得分:-1)

答案很简单:

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