这个问题与我的上一个one有关。我正在尝试使用traits<T>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()的返回类型作为const foo而不是const foo*。我在这里做错了什么?

任何帮助将是巨大的!

最佳答案

正在使用特化。 traits<foo*>::const_referenceconst foo。如果希望它成为一个指针,请使用:

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

这样,traits<foo*>::const_reference将成为const foo*

请注意,在T特化中使用traits<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]。我们可以从另一个具有形式参数sums的函数调用l:
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是特化的参数,而不是基本模板。

关于c++ - 在C++中使用特征,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2304792/

10-12 03:27