6

这个问题与我的上一个问题有关。我正在尝试使用 traits<T> and解决问题traits<T*>。请考虑以下代码。

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()asconst foo而不是返回类型const foo*。我在这里做错了什么?

任何帮助都会很棒!

4

1 回答 1

2

正在使用专业化。traits<foo*>::const_reference const foo。如果您希望它是一个指针,请使用:

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

有了这个,traits<foo*>::const_reference就会const foo*

请注意,特化中的使用T与模板traits<T*>中的 T 完全分开。traits你可以重命名它:

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]。我们可以sums从另一个函数调用,该函数本身有一个名为 的形参l

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

sumsq的“l”与“l”无关sum

使用模板,我们抽象类型名称而不是值。也就是说,我们转:

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是专业化的参数,而不是基本模板。

于 2010-02-21T04:46:09.900 回答