Reputation:
I need to know a built-in function or anyway to get the type of a variable in C++
I want to check the type of the variable in a generic method.
for INSTANCE
template<class Numbers> bool Matrix(Numbers matrix[] ,int matrixsize)
{
if (/* type of matrix is int */)
return false;
else
return true;
}
Upvotes: 0
Views: 7866
Reputation: 137928
In C++, manipulation of types falls under the umbrella term of "metaprogramming," and the function you describe would be a "metafunction."
The new Standard defines various metafunctions including one that strips array bounds and one that checks for type equivalence.
This expression evaluates to a constant true
:
std::is_same< typename std::remove_extent< int[] >::type, int >::value
With C++11, you can use this with #include <type_traits>
. With older compilers, you can probably access it through either #include <tr1/type_traits>
or #include <type_traits>
, and then use std::tr1::is_same
and std::tr1::remove_extent
.
If you want to encapsulate the expression rather than write it out each time (as it's rather ugly), it's simple to define your own metafunction:
template< typename T >
struct array_is_int {
enum { value =
std::is_same< typename std::remove_extent< int[] >::type,
int >::value
};
};
If later you want to return true
for unsigned int
as well, just modify the expression:
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
};
};
This is easier than dealing with specializations, which depend on the function overloading rules.
Upvotes: 1
Reputation: 28792
The better way to do what you stated in the comments is with template specialization:
template<class Numbers>
bool Matrix(Numbers matrix[] ,int matrixsize) {
return true;
}
template<> // full specialziation on int
bool Matrix(int matrix[] ,int matrixsize) {
return false;
}
This will branch at compile time which template to use: the first (general) one, or the second (specialized). You can have more than one specialization as well if you need
If there are places where you want to branch based on dynamic type (e.g. whether a pointer to base class actually points to a base class of one of its derivatives), you should be able to use dynamic_cast<>
in most cases:
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();
}
}
Note that the best way would be to do proper inheritance instead:
class Base {
public:
virtual Base();
virtual void myMethod();
};
class Derived : public Base {
public: void myMethod();
};
void f(Base* b) {
b->myMethod();
}
if *b
's actual type is Derived
, Derived::myMethod() is called; if *b
's actual type is Base
, Base::myMethod() is called; etc. If it makes no sense to call myMethod
on a Base
object (but does for all its derived classes), you can make it pure virtual by adding =0
to its declation in Base
. Or just define an empty body (might not work well if it needs to return a value)
Upvotes: 4
Reputation:
For as far as my decryption skills go, the comments made the question slightly more clear. What you want is template specialization.
template<class Numbers>
bool Matrix(Numbers matrix[] ,int matrixsize) {
return true;
}
template<>
bool Matrix(int matrix[] ,int matrixsize) {
return false;
}
If you want to do this at compile time, in C++11 you can use decltype
to get the type of any expression:
int my_variable;
decltype(my_variable) other_variable; // has type int
I'm not aware of any way to do this (easily) in C++03.
If you want to get the type of an object at runtime (which can be useful when dealing with polymorphism, sometimes), you can use the typeid()
operator and 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.
}
Upvotes: 2