2016-01-06 16 views
2

我的模板专业化不起作用。有谁知道我可以如何正确使用模板来实现此功能?在专业化和初级模板模板专业化由于未知的模板定义而失败

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

您可以重载而不是专门化。 (见例如http://stackoverflow.com/questions/7108033/template-specialization-vs-function-overloading) –

回答

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

虽然这可能摆脱编译器错误,专业化现在是相当无用的。 – 5gon12eder

+0

@ 5gon12eder这是为什么? – 101010

+0

@ 5gon12eder如果你想让专业化有不同的返回类型,你可以为返回类型写一个特质并且特化这个特质。 – Brian

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

返回类型必须匹配。但是,它可以作为模板,以及:

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