2015-10-13 61 views
1

this question中我引入了一個涉及模板化別名聲明部分特化的特定解決方案。一般情況在this answer中描述。假設我有一個模板類模板化別名聲明的部分專業化

template<typename T, ...> 
class X { 
    // .... 
}; 

而不是把牛逼免費和專業的其他模板參數我在其中的其他參數依賴於T的情況下,獨自對T。作爲一個非常具體的例子(比其他問題的例子更易於管理)考慮一個模板類

template<typename T, T absVal(T)> 
class Number_impl { 
private: 
    T _t; 
public: 
    Number_impl(T t): _t(t) {} 
    T abs() const {return absVal(_t);} 
}; 

可能的特例是

Number_impl<int, std::abs>; 

Number_impl<double, std::fabs>; 

(我知道有重載的abs版本,這僅僅是爲了說明。如果你願意的話,看看我的另一個例子)。

理想我想定義取決於一個參數,該類型的模板類號,從而使數<INT>等於

Number_impl<int, std::abs>; 

和數量<雙>等於

Number_impl<double, std::fabs>; 

類似於以下內容(不起作用):

template<typename T> 
using Number = Number_impl<T, nullptr>; 

template<> 
using Number<int> = Number_impl<int, std::abs>; 

template<> 
using Number<double> = Number_impl<double, std::fabs>; 

有沒有人知道是否以及如何做到這一點,或者如何以不同的方式實現同​​樣的目標?

+0

你不能專注別名模板:參見[這裏](http://stackoverflow.com/questions/7801228/can-i-spe cialize-a-class-template-with-an-alias-template),使用'__Number'作爲名字不是一個好主意 - 它保留見[這裏](http://stackoverflow.com/questions/228783/what -are最規則約-使用-AN-下劃線在-AC-標識符)。關於這個話題 - 爲什麼不使用爲FFTW提供C++封裝的fftwpp? – Rostislav

+0

@Rostislav感謝您的建議,看看FFTW ++,我會的。然而,我仍然對這個問題感興趣,認爲它可以相當普遍地出現。我會將__Number的名稱更改爲Number_impl(如Jarod42的答案中),我不知道這些名稱是保留的。 – doetoe

回答

3

正常的方式做這種事情是一樣的標準庫做它 - 一個traits類,你可以專注:

#include <iostream> 
#include <cmath> 

template<typename T> struct NumberTraits; 

template<typename T, class Traits = NumberTraits<T>> 
class Number { 
private: 
    T _t; 
public: 
    Number(T t): _t(t) {} 
    T abs() const { 
     return Traits::abs(_t); 
    } 
}; 

template<> struct NumberTraits<int> 
{ 
    static int abs(int i) { 
     return std::abs(i); 
    } 
}; 

template<> struct NumberTraits<double> 
{ 
    static double abs(double i) { 
     return std::fabs(i); 
    } 
}; 


using namespace std; 

auto main() -> int 
{ 
    Number<int> a(-6); 
    Number<double> b(-8.4); 
    cout << a.abs() << ", " << b.abs() << endl; 
    return 0; 
} 

預期輸出:

6, 8.4 
+1

優秀,非常優雅。謝謝! – doetoe

2

您可以添加一個圖層:

template<typename T, T absVal(T)> 
class Number_impl { 
private: 
    T _t; 
public: 
    Number_impl(T t): _t(t) {} 
    T abs() const {return absVal(_t);} 
}; 

template<typename T> struct Number_helper; 

template<> struct Number_helper<int> { using type = Number_impl<int, std::abs>; }; 
template<> struct Number_helper<double> { using type = Number_impl<double, std::fabs>; }; 

template<typename T> 
using Number = typename Number_helper<T>::type; 
+0

謝謝,好主意! – doetoe