2010-02-21 48 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