6

この質問は私の最後の質問に関連しています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()asとしているようです。ここで何が間違っていますか?const fooconst 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*>適用すると考えることができます。を抽象化すると、次のようになります。traitsdouble*double

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

ここでTは、基本テンプレートではなく、特殊化のパラメーターです。

于 2010-02-21T04:46:09.900 に答える