2009-04-30 6 views
4

C++では、ネームスペースとグローバルスコープ以外のスコープ(MS VSC++エラーC3412)ではメンバーテンプレートの特殊化が許可されていないようです。しかし、私にとっては、派生クラスの基本メンバテンプレートを派生クラスに特化するのは理にかなっています。なぜなら、派生クラスはそれが基本クラスのものを特殊化するからです。たとえば、次の例を考えてみましょう。メンバテンプレートの特殊化とそのスコープ

struct Base 
{ 
    template <class T> 
    struct Kind 
    { 
     typedef T type; 
    }; 
}; 

struct Derived : public Base 
{ 
    /* Not Allowed */ 
    using Base::Kind; 
    template <> 
    struct Kind <float> 
    { 
    typedef double type; 
    }; 
}; 

int main(void) 
{ 
    Base::Kind<float>::type f; // float type desired 
    Derived::Kind<float>::type i; // double type desired but does not work. 
} 

私の質問はなぜ許可されていないのですか?

+1

ところで、g ++にバグ#39906(http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39906)のバグがあり、同様のコードを誤って受け入れています。しかし、ComeauとVC++はそうではありません。 – Sumant

答えて

4

私はあなたがしようとしているものを手に入れていますが、それは正しいことではありません。これを試してみてください:

struct Base{}; 
struct Derived{}; 

// Original definition of Kind 
// Will yield an error if Kind is not used properly 
template<typename WhatToDo, typename T> 
struct Kind 
{ 
}; 

// definition of Kind for Base selector 
template<typename T> 
struct Kind<Base, T> 
{ 
    typedef T type; 
}; 

// Here is the inheritance you wanted 
template<typename T> 
struct Kind<Derived, T> : Kind<Base, T> 
{ 
}; 

// ... and the specialization for float 
template<> 
struct Kind<Derived, float> 
{ 
    typedef double type; 
}; 
1

私の質問はなぜ許可されていないのですか?次のように上記の制限置くことが表示されます草案の私のコピーから

: で

クラステンプレートの明示的な特殊宣言、クラステンプレートやクラスのメンバーのメンバーを 明示的に特殊化されたクラスの名前は、simple-template-idでなければならない。

回避策は、囲むクラスを特化することです。

1

私は標準仕様を "無視" と論理引数しようとします:

class A 
{ 
    struct S { }; 

}; 

class B: public A 
{ 
    struct S { }; 
}; 

A :: SとB :: S:あなたは2つのクラスを持っている場合

を2つの異なるタイプです。論理をテンプレートの特殊化に拡張すると、派生クラスの内部クラスを介して基本クラスで宣言された内部クラスを特殊化しようとすると、実際は同じ名前(別の命名スコープ)で別の型を定義しようとしています。

関連する問題