Bestimmung Klassentypen können Sie die Tatsache nutzen, dass das Mitglied Zeiger existieren
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;
};
Sie können nicht den Unterschied von einer Vereinigung erkennen und einer nicht gewerkschaftlich Klasse. Zumindest weiß ich nicht wie und Boost weiß es auch nicht.
Ich denke, Erkennung Enums könnte funktionieren, indem Sie sicherstellen, T
ist keine Klasse, Funktion oder Integraltyp, und dann versuchen, einen integralen Typ zuweisen. Sie könnten
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;
};
Schnell & schmutzig Test (Arbeiten auf GCC/Klappern/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 >();
}
Was bedeutet '(void) sizeof (x)'? : -/ – Nawaz
@Nawaz: Es (Casting zu "void") ist nur um den zurückgegebenen Wert zu unterdrücken. :) –
@Prasoon: hehe..das habe ich zuerst gedacht ... aber dann kam mir in den Sinn, dass, da es Johannes ist, er vielleicht etwas anderes meinte, was mir nicht bewusst ist. – Nawaz