C++ で変数の型を取得するには、組み込み関数を知る必要があります。
ジェネリック メソッドで変数の型を確認したい。
例えば
template<class Numbers> bool Matrix(Numbers matrix[] ,int matrixsize)
{
if (/* type of matrix is int */)
return false;
else
return true;
}
コメントで述べたことを行うためのより良い方法は、テンプレートの特殊化を使用することです。
template<class Numbers>
bool Matrix(Numbers matrix[] ,int matrixsize) {
return true;
}
template<> // full specialziation on int
bool Matrix(int matrix[] ,int matrixsize) {
return false;
}
これは、コンパイル時に、最初の(一般的な)テンプレートまたは2番目の(特殊な)テンプレートのどちらを使用するかを分岐します。必要に応じて、複数の専門分野を持つこともできます
動的型に基づいて分岐する場所がある場合(たとえば、基本クラスへのポインターが実際にその派生物の1つの基本クラスを指しているかどうか)、dynamic_cast<>
ほとんどの場合に使用できるはずです。
class Base {
public: virtual ~Base();
};
class Derived : public Base {
public: void mySpecialMethod();
};
void f(Base* b) {
Derived* d = dynamic_cast<Derived*> (b);
if (d != NULL) {
// *b's actual type is (derivative of) Derived
d->mySpecialMethod();
}
}
代わりに適切な継承を行うのが最善の方法であることに注意してください。
class Base {
public:
virtual Base();
virtual void myMethod();
};
class Derived : public Base {
public: void myMethod();
};
void f(Base* b) {
b->myMethod();
}
*b
の実際のタイプがの場合Derived
、Derived :: myMethod()が呼び出されます。*b
の実際のタイプが、の場合Base
、Base :: myMethod()が呼び出されます。など。オブジェクトを呼び出すことが意味をなさない場合(ただし、そのすべての派生クラスに対しては意味があります)、。のデクレーションに追加することmyMethod
で、オブジェクトを純粋な仮想にすることができます。または、空の本体を定義するだけです(値を返す必要がある場合はうまく機能しない可能性があります)Base
=0
Base
私の解読スキルに関する限り、コメントは質問をもう少し明確にしました。必要なのはテンプレートの特殊化です。
template<class Numbers>
bool Matrix(Numbers matrix[] ,int matrixsize) {
return true;
}
template<>
bool Matrix(int matrix[] ,int matrixsize) {
return false;
}
コンパイル時にこれを実行する場合は、C ++ 11decltype
で、任意の式の型を取得するために使用できます。
int my_variable;
decltype(my_variable) other_variable; // has type int
私はC++03でこれを(簡単に)行う方法を知りません。
実行時にオブジェクトの型を取得したい場合(ポリモーフィズムを処理するときに役立つ場合があります)、typeid()
演算子とを使用できますstd::type_info
。
#include <type_info>
// ...
void foo(some_virtual_class& base) {
const std::type_info& info = typeid(base);
// Do something with the type info.
}
C++ では、型の操作は「メタプログラミング」の包括的な用語に該当し、記述した関数は「メタ関数」になります。
新しい標準では、配列の境界を取り除くものや型の等価性をチェックするものなど、さまざまなメタ関数が定義されています。
この式は定数に評価されtrue
ます:
std::is_same< typename std::remove_extent< int[] >::type, int >::value
C++11 では、これを で使用できます#include <type_traits>
。#include <tr1/type_traits>
古いコンパイラでは、おそらく または のいずれかからアクセスしてから、および#include <type_traits>
を使用できます。std::tr1::is_same
std::tr1::remove_extent
式を毎回書き出すのではなくカプセル化したい場合 (かなり醜いため)、独自のメタ関数を定義するのは簡単です。
template< typename T >
struct array_is_int {
enum { value =
std::is_same< typename std::remove_extent< int[] >::type,
int >::value
};
};
true
後でforも返したい場合unsigned int
は、式を変更するだけです。
template< typename T >
struct array_is_int {
enum { value =
std::is_same< typename std::remove_extent< int[] >::type,
int >::value
|| std::is_same< typename std::remove_extent< int[] >::type,
unsigned int >::value
};
};
これは、関数のオーバーロード規則に依存する特殊化を処理するよりも簡単です。