2010-02-21 70 views
5

這個問題與我最後的one有關。我正在嘗試使用traits<T>traits<T*>解決問題。請考慮下面的代碼。在C++中使用特徵

template<typename T> 
struct traits 
{ 
    typedef const T& const_reference; 
}; 

template<typename T> 
struct traits<T*> 
{ 
    typedef const T const_reference; 
}; 

template<typename T> 
class test 
{ 
public: 
    typedef typename traits<T>::const_reference const_reference; 
    test() {} 
    const_reference value() const { 
     return f; 
    } 
private: 
    T f; 
}; 

int main() 
{ 
    const test<foo*> t; 
    const foo* f = t.value(); // error here. cannot convert ‘const foo’ to ‘const foo*’ in initialization 
    return 0; 
} 

所以它看起來像編譯器不考慮指針性狀專業化和服用value()返回類型爲const foo,而不是const foo*。我在這裏做錯了什麼?

任何幫助將是偉大的!

回答

2

正在使用專業化。 traits<foo*>::const_referenceconst foo。如果你希望它是一個指針,使用方法:

template<typename T> 
struct traits<T*> 
{ 
    typedef const T* const_reference; 
}; 

有了這個,traits<foo*>::const_referenceconst foo*

請注意,traits<T*>專業化中T的使用與traits模板中的T完全分開。你可以重命名它:

template<typename U> 
struct traits<U*> 
{ 
    typedef const U* const_reference; 
}; 

和你將有相同的專業化。如果你有功能編程經驗,這會更有意義。

首先,將template <typename ...>想象爲引入一個抽象,而不是像一個函數抽象出一個值。這就像打開

sum = 0 
for item in [1,2,3]: 
    sum += item 

到:

function sum(l): 
    sum = 0 
    for item in l: 
     sum += item 
    return sum 

其中l採取的[1,2,3]的地方。我們可以從它本身有一個名爲l形式參數另一個函數調用sums

function sumsq(l): 
    return sum(map(lambda x: x*x, l)) 

sumsq的‘L’無關與sum的‘L’。

使用模板,我們抽象類型名稱而不是值。也就是說,我們把:

struct traits { 
    typedef const double& const_reference; 
}; 

到:

template <typename T> 
struct traits { 
    typedef const T& const_reference; 
}; 

現在考慮一個非模板專業化:

template <> 
struct traits<double*> { 
    typedef const double* const_reference; 
}; 

這裏沒有對專業化模板參數,但你可以將traits<double*>視爲將traits模板應用於double*。抽象出來的double,你必須:

template <typename T> 
struct traits<T*> { 
    typedef const T* const_reference; 
}; 

這裏T是專業化,而不是基本模板的參數。

+0

我覺得dump :(但是,T本身就是一個指針('foo *')。所以指定'T *'會導致'T **'? – 2010-02-21 04:48:56

+0

不。在'traits '專精中,T '不是指針,'T *'是一個指針,你使用相同的typename參數是不重要的。 – outis 2010-02-21 04:51:39

+0

好的,謝謝。 – 2010-02-21 04:54:59