2016-09-30 1 views
0

次のことを考えてみましょう:テンプレート価値のパブリックアクセス

template<int T> 
class Test { 
public: 
    constexpr static int A = T; 
}; 

int main(int argsc, char** args) { 
    std::cout << Test<2>::T << std::endl; // Option 1 
    std::cout << Test<2>::A << std::endl; // Option 2 
} 

なぜオプション1つのコンパイルはしていませんか? static constexpr Aはほんの一歩に過ぎません。 Tは公開されていませんか?

にアクセスするクリーナーの方法は、上記のAなどの一般にアクセス可能なメンバーを作成する方法よりもですか?

+0

クラス外のテンプレートパラメータにアクセスすることはできません。 – plasmacel

+0

@plasmacel - なぜそれは本当ですか? Aを作成するステップは不要です。 – Jack

+1

また、テンプレートパラメータを取得できるような特性を作成することもできます。 'template TestTrait;テンプレート TestTrait > struct {constexpr static int value = N; }; ' – Jarod42

答えて

2

なぜオプション1はコンパイルされませんか?

テンプレートパラメータは単なるパラメータの名前なので、あなたはそれらの名前を変更することが許可されている、それは次のようになります。あなたが異なっ宣言と定義の間に、あなたの関数のパラメータに名前を付けるために許可されている同じ理由

template <class T> struct X; 

// refers to same X 
template <class U> struct X { ... }; 

// still the same X 
template <class V> 
void X<V>::foo() { ... }; 

。クラステンプレート内でテンプレートパラメータの名前を自動的に表示する必要がある場合は、最初に修正する必要があります。

上記のAのような一般にアクセス可能なメンバーを作成するよりも、Tにアクセスするクリーナーの方法はありますか?

通常、アクセス可能なメンバーを作成するのが一般的です。代わりに、外部特性を作成することもできます。

template <class T> struct X { using type = T; }; // internal 

template <class > struct get_type; 
template <class T> struct get_type<X<T>> { using type = T; }; // external 
+0

'type'が型ではなく' int'の値であれば 'using type = T'は動作しますか? – Jack

+0

@Jackいいえ、あなたは静的constexpr int値= T;を持っていなければならないでしょう。 – Barry

+0

クラスの外にあるパラメータの名前を変更できるという機能は、元の名前でパラメータにアクセスしたり、インデックスで抽出したりする機能を除外しません。したがって、それは標準による制限のようなものです。 – plasmacel