静的なconst要素を持つクラステンプレートを作成しました。その目的は、テンプレートの各特殊化がこの静的要素の独自のバージョン/値を持つことです。ここに私のサンプルコードです:コンパイルしない行についてはテンプレートの特殊化の静的constの初期化
my int
my char
my int my char
my int my char
、エラーメッセージを(GCC 4.4を使用して:
template < typename T > class C
{
public:
static const std::string NAME;
T something;
void printName() { std::cout << NAME << std::endl; }
};
class C1 : public C<int>{};
class C2 : public C<char>{};
template<> const std::string C<int>::NAME{ "my int" }; // compiles
template<> const std::string C<char>::NAME{ "my char" }; // compiles
//template<> const std::string C1::NAME{ "my int" }; // doesn't compile
//template<> const std::string C2::NAME{ "my char" }; // doesn't compile
//const std::string C1::NAME{ "my int" }; // doesn't compile
//const std::string C2::NAME{ "my char" }; // doesn't compile
int main()
{
C1 c1;
C2 c2;
c1.printName();
c2.printName();
std::cout << c1.NAME << " " << c2.NAME << std::endl;
std::cout << C1::NAME << " " << C2::NAME << std::endl;
}
コンパイルバージョンを使用して、出力は私が期待するものです)
ISO C++ does not permit 'C<int>::NAME' to be defined as 'C1::NAME'
なぜこれは許可されていませんか?私の理解では、テンプレートの完全な特殊化はすべての(?)の点でクラスであり、このクラスはテンプレートに宣言されたすべてのメンバーを持っています。だから私はスコープ解決演算子を使用して、そのクラスの静的メンバーを参照することができると期待します。どうやら、上記のメインの最後の行のように、初期化の後にそうすることはできますが、初期化自体はできません。
標準がこのように記述された理由については、誰でも洞察を提供できますか?標準で「悪い」構文が許可されていれば、どのような問題が起こるでしょうか?
それは物事をより明確にする。私はテンプレートが新しく、インスタンス化と特殊化のコンセプト、継承との組み合わせなどを整理しようとしています。これが正しいかどうかを見てみましょう:クラスC1を宣言したときのコンパイラは(暗黙の)Cのインスタンス化は、C1の基本クラスになります。静的メンバーは基本クラスに属しているため、基本クラス名 "C "を使用して初期化します。同様にC2&Cのため。 C とC には継承関係はありません。それらは同じテンプレートから生成されたばかりです。それは正しいのでしょうか? –
user3065699
私が期待していることは、C1とC2(あるいはより正確にはそれぞれの基本クラス)に、それぞれ(基本)クラスごとに異なる値を持つNAMEという静的メンバーが必要です。それが私が最終的に管理したものです。私はちょうどそれがいかに働いたか明確ではなかった。 – user3065699