本文介绍了如何知道,如果传递给函数的参数是C ++中的类,联合或枚举?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要定义一个操作<<所有枚举,来清点的价值和打印,它是这样的一个枚举:

I want to define an operator<< for all enums, to cout the value and print that it is an enum like this:

code:

enum AnyEnum{A,B,C};
AnyEnum enm = A;
cout << enm <<endl;

输出:

This is an enum which has a value equal to 0

我知道与Boost库这样通过使用 is_enum 结构的一种方式。但我不明白它是如何工作的。所以这就是为什么,在一般情况下,我有兴趣如何识别是否veriable是一个类类型,联合类型或枚举(编译时间)。

I know a way of doing this with Boost library by using is_enum struct. But I don’t understand how it works. So that's why, in general, I am interested how to identify if the veriable is a class type, union type or an enum (in compile time).

推荐答案

确定类的类型,你可以使用该成员指针存在的事实

Determining class types you could use the fact that member pointers exist

template<typename A, typename B>
struct issame { };

template<typename A>
struct issame<A, A> { typedef void type; };

template<typename> struct tovoid { typedef void type; };

template<typename T, typename = void>
struct isclass { static bool const value = false; };

template<typename C>
struct isclass<C, typename tovoid<int C::*>::type> {
  static bool const value = true;
};

您无法检测到工会和非工会类的差异。至少我不知道怎么了,不刺激也不知道。

You cannot detect the difference of an union and a non-union class. At least I don't know how, and boost doesn't know either.

我想检测枚举可以通过确保工作 T 不是一个类,函数或整型,然后试图分配为整型。你可以

I think detecting enums could work by making sure T isn't a class, function or integral type, and then trying to assign to an integral type. You could

template<typename E, typename = void> 
struct isenum { 
  struct No { char x; };
  struct Yes { No n1; No n2; };

  struct nullsink {};
  static No checkI(nullsink*); // accept null pointer constants
  static Yes checkI(...);

  static Yes checkE(int);
  static No checkE(...);

  static bool const value = (sizeof(checkI(E())) == sizeof(Yes)) && 
                            (sizeof(checkE(E())) == sizeof(Yes));
};

// class
template<typename E>
struct isenum<E, typename tovoid<int E::*>::type> {
  static bool const value = false;
};

// reference
template<typename R>
struct isenum<R&, void> {
  static bool const value = false;
};

// function (FuntionType() will error out).
template<typename F>
struct isenum<F, typename issame<void(F), void(F*)>::type> {
  static bool const value = false;
};

// array (ArrayType() will error out)
template<typename E>
struct isenum<E[], void> {
  static bool const value = false;
};
template<typename E, int N>
struct isenum<E[N], void> {
  static bool const value = false;
};

快速和放大器;肮脏的测试(适用于GCC /哗/科莫):

Quick & dirty test (works on GCC/clang/comeau):

enum A { };
struct B { };
typedef int &C;
typedef void D();
typedef int E;
typedef long F;
typedef int const G;
typedef int H[1];

template<typename T, bool E>
struct confirm { typedef char x[(T::value == E) ? 1 : -1]; };

int main() {
  confirm< isenum<A>, true >();
  confirm< isenum<B>, false >();
  confirm< isenum<C>, false >();
  confirm< isenum<D>, false >();
  confirm< isenum<E>, false >();
  confirm< isenum<F>, false >();
  confirm< isenum<G>, false >();
  confirm< isenum<H>, false >();
}

这篇关于如何知道,如果传递给函数的参数是C ++中的类,联合或枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 03:41