メンバーテンプレートの特化とそのスコープ
-
03-07-2019 - |
質問
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.
}
私の質問は、なぜ許可されないのですか?
解決
あなたがやろうとしていることはわかっていますが、あなたはそれを正しく行っていません。これを試してください:
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;
};
他のヒント
私の質問は、なぜ許可されないのですか?
下書きのコピーから、次のことが上記の制限を課しているようです:
で クラステンプレート、クラステンプレートのメンバー、またはクラスメンバーの明示的な特殊化宣言 テンプレートの場合、明示的に特化されたクラスの名前はsimple-template-idでなければなりません。
回避策は、包含するクラスを特化することです。
「無視」します;標準仕様を作成し、論理引数を試します:
2つのクラスがある場合:
class A
{
struct S { };
};
class B: public A
{
struct S { };
};
A :: SとB :: Sは2つの異なるタイプです。ロジックをテンプレートの特殊化に拡張し、派生クラスの内部クラスを介して基本クラスで宣言された内部クラスを特殊化しようとすると、実際には同じ名前(ただし、別の名前付けスコープ)で異なる型を定義しようとします。 / p>
所属していません StackOverflow