如何在C++中获取变量类型

how to get typeof variable in C++

本文关键字:获取 变量 类型 C++      更新时间:2023-10-16

我需要知道一个内置函数,或者无论如何才能在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();等等。 如果在Base对象上调用myMethod没有意义(但对其所有派生类都这样做),则可以通过在Base中的引用中添加=0来使其成为纯虚拟。 或者只是定义一个空体(如果需要返回一个值,则可能无法正常工作)

新答案

就我的解密技能而言,这些评论使问题稍微清晰一些。你想要的是模板专业化。

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()运算符和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_samestd::tr1::remove_extent

如果你想封装表达式而不是每次都写出来(因为它相当丑陋),定义你自己的元函数很简单:

template< typename T >
struct array_is_int {
    enum { value =
        std::is_same< typename std::remove_extent< int[] >::type,
                         int >::value
    };
};

如果以后您也想为 unsigned int 返回 true,只需修改表达式:

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
    };
};

这比处理专用化更容易,后者依赖于函数重载规则。