C++のis_polymorphicテンプレートの使い方を徹底解説
本記事では、C++標準ライブラリ(STL)に含まれる std::is_polymorphic テンプレートの仕組み、構文、そして具体的な使用例について詳しく解説します。
is_polymorphic は、C++の <type_traits> ヘッダーファイルで定義されているテンプレートです。指定したクラスが「多態クラス(ポリモーフィッククラス)」であるかどうかをコンパイル時に判定し、その結果を true または false として返します。
多態クラスとは?
多態クラスとは、仮想関数(virtual関数)を持つクラスのことです。具体的には、以下のいずれかに該当するクラスが該当します。
- 自身で仮想関数を宣言しているクラス
- 基底クラスから仮想関数を継承している派生クラス
仮想関数が1つでも存在すれば、そのクラスは多態クラスとみなされます。
構文
template <class T> is_polymorphic;
パラメータ
このテンプレートは、判定対象となる型 T を1つだけ受け取ります。そして、その型が多態クラスであるかどうかをチェックします。
戻り値
ブール値(bool)を返します。
- 指定された型が多態クラスの場合 →
true - 指定された型が多態クラスでない場合 →
false
使用例(入出力イメージ)
入力:class B { virtual void fn(){} };
class C : B {};
is_polymorphic<B>::value;
出力:True
入力:class A {};
is_polymorphic<A>::value;
出力:False仮想関数を持つクラスBに対しては true が返され、何も持たない空のクラスAに対しては false が返されることがわかります。
サンプルコード1:仮想関数を持つクラスの判定
#include <iostream>
#include <type_traits>
using namespace std;
struct TP {
virtual void display();
};
struct TP_2 : TP {
};
class TP_3 {
virtual void display() = 0;
};
struct TP_4 : TP_3 {
};
int main() {
cout << boolalpha;
cout << "Checking for is_polymorphic: ";
cout << "\n structure TP with one virtual function : "<<is_polymorphic<TP>::value;
cout << "\n structure TP_2 inherited from TP: "<<is_polymorphic<TP_2>::value;
cout << "\n class TP_3 with one virtual function: "<<is_polymorphic<TP_3>::value;
cout << "\n class TP_4 inherited from TP_3: "<< is_polymorphic<TP_4>::value;
return 0;
}実行結果
上記のコードを実行すると、次のような出力が得られます。
Checking for is_polymorphic: structure TP with one virtual function : true structure TP_2 inherited from TP: true class TP_3 with one virtual function: true class TP_4 inherited from TP_3: true
この例では、仮想関数を直接宣言している TP や純粋仮想関数を持つ抽象クラス TP_3 だけでなく、それらを継承した TP_2 や TP_4 もすべて true と判定されています。これは、仮想関数を継承した時点で多態クラスになるためです。
サンプルコード2:非多態クラスとの比較
#include <iostream>
#include <type_traits>
using namespace std;
struct TP {
int var;
};
struct TP_2 {
virtual void display();
};
class TP_3: TP_2 {
};
int main() {
cout << boolalpha;
cout << "Checking for is_polymorphic: ";
cout << "\n structure TP with one variable : "<<is_polymorphic<TP>::value;
cout << "\n structure TP_2 with one virtual function : "<<is_polymorphic<TP_2>::value;
cout << "\n class TP_3 inherited from structure TP_2: "<<is_polymorphic<TP_3>::value;
return 0;
}実行結果
上記のコードを実行すると、次のような出力が得られます。
Checking for is_polymorphic: structure TP with one variable : false structure TP_2 with one virtual function : true class TP_3 inherited from structure TP_2 : true
この例では、通常のメンバ変数のみを持つ TP は false と判定され、仮想関数を持つ TP_2 およびそれを継承する TP_3 は true と判定されています。
まとめ
std::is_polymorphic は、型が多態クラス(仮想関数を持つクラス)であるかをコンパイル時に判定できる便利なタイプトレイトです。テンプレートメタプログラミングや、条件に応じた処理の分岐などに活用できます。判定結果は ::value メンバを通じて true / false として取得できる点を覚えておきましょう。
-
C++における構造体とクラスの違いとは?アクセス指定子の挙動を実例付きで解説
はじめにC++において、構造体(struct)とクラス(class)は本質的にはほぼ同じものです。どちらもメンバ変数やメンバ関数を持つことができ、継承・カプセル化といったオブジェクト指向の機能も同様に利用できます。しかし、両者にはいくつかの細かな違いが存在します。この記事では、その違いをサンプルコードと実行結果を交えてわかりやすく解説します。違い1:メンバのデフォルトのアクセスレベル最も大きな違いは、メンバのデフォルトのアクセス権限です。クラスのメンバはデフォルトで「private(非公開)」になりますが、構造体のメンバはデフォルトで「public(公開)」になります。実際に、以下の2つのコー
-
C++のローカルクラスとは?特徴・制約と実装例をわかりやすく解説
ローカルクラスとは C++において、関数の中で宣言されたクラスは「ローカルクラス」と呼ばれます。これは、そのクラスが定義された関数の内部でのみ有効であるためです。 まず、ローカルクラスの基本的な構造を見てみましょう。 #include<iostream> using namespace std; void func() { class LocalClass { }; } int main() { return 0; } 上記の例では、関数 func() の中で LocalClass が定義されています。このように関数の内部で宣言されたクラスが、ローカルクラス