LoginSignup
33
24

More than 5 years have passed since last update.

templateクラスのstaticメンバ変数

Last updated at Posted at 2015-01-14

イントロ

通常のクラス同様、templateクラス内にも静的メンバ変数を用意することができる。しかし、その実体の用意の方法は特殊化の方法や有無によって異なる。少しハマってしまったので、覚書としてまとめておく。すでに知っていた人は、何を今頃、とでも思いながら眺めてください。

非templateクラス内の静的メンバ

比較のために、まず通常のクラス中での静的メンバ変数の宣言を書いてみる。

non_template_static_value.hpp
class Hoge{
    static int Value;
};
non_template_static_value.cpp
#include "non_template_static_value.hpp"
int Hoge::Value=0;

staticメンバ変数の実体は、当然ソースファイルに別に記述する必要がある。

templateクラス内での静的メンバ

次にtemplateクラス内で、静的メンバ変数を宣言した場合。

template_static_value.hpp
template<typename A>
class Hoge{
    static int Value;
};

template<typename A>
int Hoge<A>::Value=0;

templateクラス内の静的メンバの場合には、template宣言template<typename A>とともに静的メンバ変数の実体をヘッダファイル内に記述する。

明示的特殊化したクラス内での静的メンバ変数

さて、次にtemplateクラスを明示的特殊化したクラス内でのみ、静的メンバ変数を使いたい状況を考えてみる。

explicit_specialization_static_value.hpp
template<typename A>
class Hoge{
};
template<>
class Hoge<int>{
    static int Value;
};
explicit_specialization_static_value.cpp
#include"explicit_specialization_static_value.hpp"
int Hoge<int>::Value=0;

明示的特殊化したクラスで宣言した変数の実体は、すでにintで確定しているため、template非依存なので、静的メンバ変数の実体は非templateクラス同様template宣言なしでソースファイルに実体を用意する必要がある。

これは、スタックオーバーフローでの質問で初めて気づいた。回答者様、ありがとうございます。

部分的特殊化したクラス内の静的メンバ

同じ特殊化でも、部分的特殊化の場合には、また変わってくる。

partial_specialization_static_value.hpp
template<typename A>
class Hoge{
};
template<typename A>
class Hoge<A*>{
    static int Value;
};
template<typename A>
int Hoge<A*>::Value=0;

部分特殊化したクラスで宣言した変数の実体は、まだtemplate依存なので、通常のtemplateクラス同様、template宣言template<typename A>とともにヘッダファイル内に静的メンバ変数の実体を記述する。

ネストされたtemplateの静的メンバ

templateが複数ネストされている場合も少しややこしい。

nested_template_static_value.hpp
template<typename A>
class Hoge{
    template<typename B>
    class Fuga{
        static int Value;
    };
};
template<typename A>
template<typename B>
int Hoge<A>::Fuga<B>::Value=0;

templateがネストされている場合、変数の実体宣言時には、template宣言template<typename ???>を必要なだけ重ねることで宣言できる。

結論

非templateクラスや、templateの明示的特殊化クラス内の静的メンバ変数
=> template宣言なしで、ソースに実体を用意

templateクラスや、templateの部分特殊化クラス内の静的メンバ変数
=> template宣言とともにヘッダで実体を用意

templateクラスがネストされている場合
=> 必要なだけtamplate宣言を重ねて、ヘッダに実体を用意

33
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
24