0

我需要知道一个内置函数或者无论如何要在 C++ 中获取变量的类型

我想在泛型方法中检查变量的类型。

例如

template<class Numbers> bool Matrix(Numbers matrix[] ,int matrixsize)
{
 if (/* type of matrix is int */)
   return false;
 else
   return true;
} 
4

3 回答 3

4

执行您在评论中所说的更好的方法是使用模板专业化:

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(但对它的所有派生类都有效),你可以通过=0Base. 或者只是定义一个空主体(如果它需要返回一个值可能效果不佳)

于 2012-04-15T10:26:59.287 回答
2

新答案

就我的解密技巧而言,评论使问题更加清晰。你想要的是模板专业化。

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.
}
于 2012-04-15T10:20:20.860 回答
1

在 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_sameand std::tr1::remove_extent

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

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

如果稍后您也想返回trueunsigned 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
    };
};

这比处理依赖于函数重载规则的特化更容易。

于 2012-04-15T10:35:52.383 回答