2013-04-15 57 views
0

我有template,我有方法T get(int i)set(int i, T val)。我必須做出不改變行爲的特質類別,但是具有setget的爭論。具有特徵的模板方法的C++更改行爲

template<typename T,int Roz> 
class Wektor{ 
public: 
T tab[Roz]; 
T get(int i) 
{ 
    return tab[i]; 
} 
void set(T val,int i) 
{ 
    tab[i]=val; 
} 
} 

所以特質類必須改變get和set。如果T是int或double,我們得到的副本 INT

int get(int i); 
void set(int val,int i); 

double get(int i); 
void set(double val,int i); 

parametr他人類型:

T* get(int i); 
void set(T* val,int i); 

,我們必須特質不是模板的專業化辦。

所以我寫tratis這樣的:

template<typename T,int Roz> 
class traitsWektor 
{ 
public: 
T tab[Roz]; 
T get(int i) 
{ 
    return tab[i]; 
} 
void set(T val,int i) 
{ 
    tab[i]=val; 
} 
} 

所以我在這裏停留。我想我應該讓

template<typename T, int Roz> 
class Wektor : public traitsWektor<T,Roz> 

但我不知道是正確的,仍然是tratis。

回答

4

你應該分開類模板(Wektor)和參數類型推演:

template <class T> 
struct WektorParamTraits { 
    typedef T const& type; 

    //or if you might have different types as getter return type and setter arg 
    typedef T const& getterReturn; 
    typedef T const& setterArg; 
}; 

在這種情況下,T是「默認」類型,您的getter/setter參數。專門爲您需要的任何類型。 類定義現在應該如下:

template<typename T,int Roz> 
class Wektor{ 
    T tab[Roz]; //make member variables private 
public: 
    typename WektorParamTraits<T>::getterReturn get(int i) //const? 
    { 
    return tab[i]; 
    } 

    void set(typename WektorParamTraits<T>::setterArg val,int i) 
    { 
    tab[i]=val; 
    } 
}; 

更新:在評論中指出的那樣,你可能需要定義get和set如其他實現如果你的返回類型是一個指針。有幾種不同的方法來做到這一點:

  1. 定義性狀功能正常tab[i]和參數/返回值之間的轉換。
  2. 如果只關於指針和非指針,請提供兩個版本的獲取器和設置器,並使用std::enable_ifstd::is_pointer以及其他任何需要禁用其中一個的方法。
  3. 使用您在此處發佈的簡單類定義,並將其專門化爲少數不使用常規引用的類型。任何進一步的功能都應該進入非專門化的子類。

方法2將是非常詳細和難以閱讀。方法1也是冗長的,因爲除了將數組定義指向特徵類外,您幾乎可以將的所有東西都委託給,因此您可以使用方法3,因爲這不是太遙遠。

+0

問題是你還需要不同的實現GET'的'和'set'當返回類型是一個指針。 – jrok

0

我覺得這個模板可以幫助你:

template<typename T> 
class traits 
{ 
public: 
    typedef T * result; 
}; 

template<> 
class traits<int> 
{ 
public: 
    typedef int result; 
}; 

template<> 
class traits<double> 
{ 
public: 
    typedef double result; 
}; 


traits<int>::result; // is int. 
traits<char>::result; // is char *. 
0

我不知道你想怎麼實現set(T*,int)。但對於get你可能想試試這個

template<typename T, size_t Roz> 
class Wektor 
{ 
public: 
    template<typename U=T> 
    typename std::enable_if<std::is_arithmetic<U>::value, U>::type 
     Get(size_t n) 
    { 
     return tab[n]; 
    } 

    template<typename U=T> 
    typename std::enable_if<!std::is_arithmetic<U>::value, U*>::type 
     Get(size_t n) 
    { 
     return &tab[n]; 
    } 

    T tab[Roz]; 
};