2016-01-06 63 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