我需要知道一个内置函数或者无论如何要在 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;
}
这将在编译时分支使用哪个模板:第一个(通用)或第二个(专用)。如果需要,您也可以拥有多个专业
如果您想根据动态类型进行分支(例如,指向基类的指针是否实际上指向其派生类之一的基类),您应该能够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++11 中您可以使用它decltype
来获取任何表达式的类型:
int my_variable;
decltype(my_variable) other_variable; // has type int
我不知道在 C++03 中有任何方法可以(轻松地)做到这一点。
如果您想在运行时获取对象的类型(有时这在处理多态性时很有用),您可以使用typeid()
运算符 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.
}
在 C++ 中,类型的操作属于“元编程”的总称,您描述的函数将是“元函数”。
新标准定义了各种元函数,包括一种去除数组边界的元函数和一种检查类型等价的元函数。
此表达式的计算结果为常量true
:
std::is_same< typename std::remove_extent< int[] >::type, int >::value
使用 C++11,您可以将其与#include <type_traits>
. 使用较旧的编译器,您可能可以通过#include <tr1/type_traits>
or访问它#include <type_traits>
,然后使用std::tr1::is_same
and 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
,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
};
};
这比处理依赖于函数重载规则的特化更容易。