由于未知的模板定义,模板特化失败

时间:2016-01-06 22:49:07

标签: c++ c++11

我的模板专业化不起作用。有谁知道如何使用模板正确实现此功能?

template<class T>
float hz_to_nsec(const T &freq) {
    return freq != 0 ? static_cast<float>(NSEC_PER_SEC) / freq : 0;
}

template <>
double hz_to_nsec<double>(const double &freq) {
    return freq != 0 ? static_cast<double>(NSEC_PER_SEC) / freq : 0;
}

4 个答案:

答案 0 :(得分:7)

专业化时返回类型,主模板必须匹配:

template<class T>
float hz_to_nsec(const T &freq) {
    return freq != 0 ? static_cast<float>(NSEC_PER_SEC) / freq : 0;
}

template <>
float hz_to_nsec<double>(const double &freq) {
^^^^^
    return freq != 0 ? static_cast<float>(NSEC_PER_SEC) / freq : 0;
                                   ^^^^^
}

或者,您可以提供重载而不是模板专业化:

template<class T>
float hz_to_nsec(const T &freq) {
    return freq != 0 ? static_cast<float>(NSEC_PER_SEC) / freq : 0;
}

double hz_to_nsec(const double &freq) {
    return freq != 0 ? static_cast<double>(NSEC_PER_SEC) / freq : 0;
}

答案 1 :(得分:5)

answer by @101010解决了您的模板错误。但是,您不需要第二个函数作为模板特化。它可能只是一个过载。

// template <>
// No need to use template specialization.
// Just use an overload.
double hz_to_nsec(double freq) {
    return freq != 0 ? static_cast<double>(NSEC_PER_SEC) / freq : 0;
}

答案 2 :(得分:2)

返回类型必须匹配。但是,它也可以模板化:

template<class T>
T hz_to_nsec(const T &freq) {
    return freq != 0 ? static_cast<float>(NSEC_PER_SEC) / freq : 0;
}

template <>
double hz_to_nsec<double>(const double &freq) {
    return freq != 0 ? static_cast<double>(NSEC_PER_SEC) / freq : 0;
}

或者您可以使用特征:

template<class T>
struct RetT
{
    using Type = float;
};

template <>
struct RetT<double>
{
    using Type = double;
};

template<class T>
typename RetT<T>::Type hz_to_nsec(const T &freq) {
    return freq != 0 ? static_cast<float>(NSEC_PER_SEC) / freq : 0;
}

template <>
double hz_to_nsec<double>(const double &freq) {
    return freq != 0 ? static_cast<double>(NSEC_PER_SEC) / freq : 0;
}

或者您甚至不需要模板专业化,您只需重载该功能:

template<class T>
float hz_to_nsec(const T &freq) {
    return freq != 0 ? static_cast<float>(NSEC_PER_SEC) / freq : 0;
}

double hz_to_nsec(const double &freq) {
    return freq != 0 ? static_cast<double>(NSEC_PER_SEC) / freq : 0;
}

答案 3 :(得分:1)

我认为专业化是错误的工具。相反,请考虑将目标类型作为附加类型参数。

// C++14

template <typename OutputT, typename InputT>
std::enable_if_t
<
  std::is_arithmetic<InputT>::value && std::is_floating_point<OutputT>::value,
  OutputT
>
hz_to_nsec(const InputT freq)
{
  return (freq != InputT {0})
    ? static_cast<OutputT>(NSEC_PER_SEC) / static_cast<OutputT>(freq)
    : OutputT {0};
}

我先把OutputT放在首位,因为无法推断出来。我还将InputTOutputT的允许类型限制为可能合理的类型。

可以像这样使用。

hz_to_nsec<double>(10);    // InputT = int,           OutputT = double
hz_to_nsec<float>(10.0f):  // InputT = float,         OutputT = float
hz_to_nsec<float>(5UL);    // InputT = unsigned long, OutputT = float