Check für is member function pointer



  • Nash26 schrieb:

    template <typename T, typename C> struct is_mem_fun_ptr<T C::*> : is_function<T> {};
    

    Für welchen Typ T wird dieses template instanziert, obwohl es keine member function ist?

    Wenn der Parameter nicht auf diese Spezialisierung passt, wird das Default-Template genommen:

    template <typename T> struct is_mem_fun_ptr : false_type {};
    


  • @wxSkip
    das heißt also ich kann direkt

    template <typename T, typename C> struct is_mem_fun_ptr<T C::*> : true_type {};
    

    schreiben?



  • Nash26 schrieb:

    @wxSkip
    das heißt also ich kann direkt

    template <typename T, typename C> struct is_mem_fun_ptr<T C::*> : true_type {};
    

    schreiben?

    Nein. Es gibt auch Nicht-Memberfunktions-Typen, die auf diese Spezialisierung passen. Und zwar sind das die relativ unbekannten Zeiger auf Member. Wenn du eine Klasse mit verschiedenen Variablen hast, kannst du einen Zeiger auf eine Klassenvariable holen, der praktisch die interne Position in der Klasse speichert. Wenn du dann noch ein konkretes Objekt hast, kannst du mit diesem Zeiger auf die Variable dieses Objektes zugreifen.


  • Mod

    Nash26 schrieb:

    jetzt zu dem Konstrukt:

    template <typename T> struct is_function : is_same<void(void(int,int)),void(void(*)(int,int))> {};
    

    Auf der linken Seite deklarierst du einen Funktionszeiger, dieser wird durch den compiler nochmal 😕 zu einem Funktionszeiger transformiert? Auf der rechten Seite machen wir das manuell. Ist das so korrekt?

    Links wird ein Funktionstyp deklariert, rechts wird ein Funktionstyp deklariert. Beiden Typen haben ihrerseits einen Funktionszeiger als Parametertyp.

    Nash26 schrieb:

    PS: wo lernt man solche Tricks mit

    is_same<void(T),void(T*)> {};

    ?
    Also das wäre mit nicht im traum eingefallen.

    Den Trick als solchen habe ich mir on-the-fly beim Schreiben ausgedacht. Den zugrunde liegenden Mechanismus lernt man irgendwann nebenbei kennen, wenn es um etwas ganz anderes geht.



  • @camper
    tja bleibt nur noch die Frage warum es mit VS2008 nicht mit const methoden klappt.
    Hast du einen workaround dafür?



  • ich bekomme es einfach nicht hin:

    template <typename T, typename C> struct is_mem_fun_ptr<T const C::*> : is_function<T> {};
    

    wenn ich das template mit einer const member function aufrufe wird sofort:

    template <typename T> struct is_mem_fun_ptr : false_type {};
    

    instanziiert

    auch den const qualifier zu entfernen klappt nicht.


  • Mod

    Nash26 schrieb:

    @camper
    tja bleibt nur noch die Frage warum es mit VS2008 nicht mit const methoden klappt.
    Hast du einen workaround dafür?

    Nein. Es gilt dann einfach das, was ich zuerst gesagt habe.

    Nash26 schrieb:

    ich bekomme es einfach nicht hin:

    template <typename T, typename C> struct is_mem_fun_ptr<T const C::*> : is_function<T> {};
    

    wenn ich das template mit einer const member function aufrufe wird sofort:

    template <typename T> struct is_mem_fun_ptr : false_type {};
    

    instanziiert

    auch den const qualifier zu entfernen klappt nicht.

    Das ist kein Wunder.
    Einen const/volatile-Qualifizierer zu einem Funktionstyp hinzuzufügen macht daraus gerade keinen const/volatile-Funktionstyp, je nach Kontext ist es schlicht illegal oder wird ignoriert.

    Die Spezialisierung

    template <typename T, typename C> struct is_mem_fun_ptr<T const C::*> : is_function<T> {};
    

    würde folglich nur für Zeiger auf konstante Member (also vor allem keine Memberfunktionen) genutzt werden.

    boost.type_traits hat bereits eine portable Lösung. Ich kann keine Bessere anbieten.



  • du hattest geschrieben

    Das Testen auf non-const-non-volatile-Memberfunktionszeiger ist einfach. Schwierigkeiten machen nur const,volatile und const volatile-Memberfunktionen:

    das heißt also, es gibt für VS2008 nur die Möglichkeit auf viele Spezialiserungen zu testen? Korrekt?


  • Mod

    Nash26 schrieb:

    du hattest geschrieben

    Das Testen auf non-const-non-volatile-Memberfunktionszeiger ist einfach. Schwierigkeiten machen nur const,volatile und const volatile-Memberfunktionen:

    das heißt also, es gibt für VS2008 nur die Möglichkeit auf viele Spezialiserungen zu testen? Korrekt?

    Das, oder Ausschlussverfahren

    #include <cstddef>
    
    template <bool b> struct bool_ { static const bool value = b; };
    template <typename T> struct not_ { static const bool value = !T::value; };
    typedef bool_<true> true_type;
    typedef bool_<false> false_type;
    
    template <typename T> struct identity { typedef T type; };
    
    // is_same
    template <typename T, typename U> struct is_same : false_type {};
    template <typename T> struct is_same<T, T> : true_type {};
    
    // add_reference
    template <typename T> struct add_reference : identity<T&> {};
    template <typename T> struct add_reference<T&> : identity<T&> {};
    
    // remove_reference (funktioniert auch mit rvalue-Referenzen)
    template <typename T> struct remove_reference : remove_reference<typename add_reference<T>::type> {};
    template <typename T> struct remove_reference<T&> : identity<T> {};
    
    // is_reference (funktioniert auch mit rvalue-Referenzen)
    template <typename T> struct is_reference : not_<is_same<T, typename remove_reference<typename add_reference<T>::type>::type> > {};
    
    // is_pointer
    template <typename T> struct is_pointer : false_type {};
    template <typename T> struct is_pointer<T*> : true_type {};
    
    // is_class (class/struct/union)
    template <typename T> struct is_class
    {
        typedef char& yes_type;
        typedef char (&no_type)[2];
        template <typename U> static no_type test(...);
        template <typename U> static yes_type test(int U::*);
        static const bool value = sizeof test<T>(0) == sizeof(yes_type);
    };
    
    // is_array
    template <typename T> struct is_array : false_type {};
    template <typename T> struct is_array<T[]> : true_type {};
    template <typename T, std::size_t N> struct is_array<T[N]> : true_type {};
    
    // is_void
    template <typename T> struct is_void : false_type {};
    template <> struct is_void<void> : true_type {};
    template <> struct is_void<const void> : true_type {};
    template <> struct is_void<volatile void> : true_type {};
    template <> struct is_void<const volatile void> : true_type {};
    
    // is_function
    template <typename T, bool = !is_void<T>::value && !is_reference<T>::value> struct is_function : is_same<void(T),void(T*)> {};
    template <typename T> struct is_function<T, false> : false_type {};
    
    // is_convertible
    template <typename T, typename U> struct is_convertible
    {
        static typename add_reference<T>::type makeT();
        typedef char& yes_type;
        typedef char (&no_type)[2];
        static no_type test(...);
        static yes_type test(U);
        static const bool value = sizeof test(makeT()) == sizeof(yes_type);
    };
    
    // is_convertible_static
    template <typename T, typename U> struct is_convertible_static
    {
        static typename add_reference<T>::type makeT();
        typedef char& yes_type;
        typedef char (&no_type)[2];
        template <typename V> static no_type test(...);
        template <typename V> static yes_type test(char(*)[sizeof(static_cast<V>(makeT()))]);
        static const bool value = sizeof test<U>(0) == sizeof(yes_type);
    };
    
    // is_fundamental_or_enum (including scoped enums)
    template <typename T> struct is_fundamental_or_enum : bool_<is_void<T>::value || ( !is_class<T>::value && !is_reference<T>::value && is_convertible_static<T, int>::value )> {};
    
    // is_mem_data_ptr
    template <typename T> struct is_mem_data_ptr : false_type {};
    template <typename T, typename C> struct is_mem_data_ptr<T C::*> : not_<is_function<T> > {};
    
    // is_mem_fun_ptr
    template <typename T> struct is_mem_fun_ptr : bool_<!is_fundamental_or_enum<T>::value && !is_class<T>::value && !is_pointer<T>::value && !is_reference<T>::value
                                                        && !is_function<T>::value && !is_array<T>::value && !is_mem_data_ptr<T>::value> {};
    
    #include <iostream>
    
    enum A { a, b, c };
    enum class B { d, e, f };
    struct C {};
    union D {};
    
    int main()
    {
        using std::cout;
        cout << "\t\t\tint\tint&\tint&&\tint[6]\tint*\tint()\tint(*)();int(&)();enum A;ec B\tstructC\tunionD\tint D::*;int(D::*)();int(D::*)const\n";
        cout << "is_reference\t" << '\t';
        cout << is_reference<int>::value << '\t';
        cout << is_reference<int&>::value << '\t';
        cout << is_reference<int&&>::value << '\t';
        cout << is_reference<int[6]>::value << '\t';
        cout << is_reference<int*>::value << '\t';
        cout << is_reference<int()>::value << '\t';
        cout << is_reference<int(*)()>::value << '\t';
        cout << is_reference<int(&)()>::value << '\t';
        cout << is_reference<A>::value << '\t';
        cout << is_reference<B>::value << '\t';
        cout << is_reference<C>::value << '\t';
        cout << is_reference<D>::value << '\t';
        cout << is_reference<int D::*>::value << '\t';
        cout << is_reference<int (D::*)()>::value << '\t';
        cout << is_reference<int (D::*)()const>::value << '\n';
    
        cout << "is_array\t" << '\t';
        cout << is_array<int>::value << '\t';
        cout << is_array<int&>::value << '\t';
        cout << is_array<int&&>::value << '\t';
        cout << is_array<int[6]>::value << '\t';
        cout << is_array<int*>::value << '\t';
        cout << is_array<int()>::value << '\t';
        cout << is_array<int(*)()>::value << '\t';
        cout << is_array<int(&)()>::value << '\t';
        cout << is_array<A>::value << '\t';
        cout << is_array<B>::value << '\t';
        cout << is_array<C>::value << '\t';
        cout << is_array<D>::value << '\t';
        cout << is_array<int D::*>::value << '\t';
        cout << is_array<int (D::*)()>::value << '\t';
        cout << is_array<int (D::*)()const>::value << '\n';
    
        cout << "is_pointer\t" << '\t';
        cout << is_pointer<int>::value << '\t';
        cout << is_pointer<int&>::value << '\t';
        cout << is_pointer<int&&>::value << '\t';
        cout << is_pointer<int[6]>::value << '\t';
        cout << is_pointer<int*>::value << '\t';
        cout << is_pointer<int()>::value << '\t';
        cout << is_pointer<int(*)()>::value << '\t';
        cout << is_pointer<int(&)()>::value << '\t';
        cout << is_pointer<A>::value << '\t';
        cout << is_pointer<B>::value << '\t';
        cout << is_pointer<C>::value << '\t';
        cout << is_pointer<D>::value << '\t';
        cout << is_pointer<int D::*>::value << '\t';
        cout << is_pointer<int (D::*)()>::value << '\t';
        cout << is_pointer<int (D::*)()const>::value << '\n';
    
        cout << "is_function\t" << '\t';
        cout << is_function<int>::value << '\t';
        cout << is_function<int&>::value << '\t';
        cout << is_function<int&&>::value << '\t';
        cout << is_function<int[6]>::value << '\t';
        cout << is_function<int*>::value << '\t';
        cout << is_function<int()>::value << '\t';
        cout << is_function<int(*)()>::value << '\t';
        cout << is_function<int(&)()>::value << '\t';
        cout << is_function<A>::value << '\t';
        cout << is_function<B>::value << '\t';
        cout << is_function<C>::value << '\t';
        cout << is_function<D>::value << '\t';
        cout << is_function<int D::*>::value << '\t';
        cout << is_function<int (D::*)()>::value << '\t';
        cout << is_function<int (D::*)()const>::value << '\n';
    
        cout << "is_class\t" << '\t';
        cout << is_class<int>::value << '\t';
        cout << is_class<int&>::value << '\t';
        cout << is_class<int&&>::value << '\t';
        cout << is_class<int[6]>::value << '\t';
        cout << is_class<int*>::value << '\t';
        cout << is_class<int()>::value << '\t';
        cout << is_class<int(*)()>::value << '\t';
        cout << is_class<int(&)()>::value << '\t';
        cout << is_class<A>::value << '\t';
        cout << is_class<B>::value << '\t';
        cout << is_class<C>::value << '\t';
        cout << is_class<D>::value << '\t';
        cout << is_class<int D::*>::value << '\t';
        cout << is_class<int (D::*)()>::value << '\t';
        cout << is_class<int (D::*)()const>::value << '\n';
    
        cout << "is_fund_or_enum\t" << '\t';
        cout << is_fundamental_or_enum<int>::value << '\t';
        cout << is_fundamental_or_enum<int&>::value << '\t';
        cout << is_fundamental_or_enum<int&&>::value << '\t';
        cout << is_fundamental_or_enum<int[6]>::value << '\t';
        cout << is_fundamental_or_enum<int*>::value << '\t';
        cout << is_fundamental_or_enum<int()>::value << '\t';
        cout << is_fundamental_or_enum<int(*)()>::value << '\t';
        cout << is_fundamental_or_enum<int(&)()>::value << '\t';
        cout << is_fundamental_or_enum<A>::value << '\t';
        cout << is_fundamental_or_enum<B>::value << '\t';
        cout << is_fundamental_or_enum<C>::value << '\t';
        cout << is_fundamental_or_enum<D>::value << '\t';
        cout << is_fundamental_or_enum<int D::*>::value << '\t';
        cout << is_fundamental_or_enum<int (D::*)()>::value << '\t';
        cout << is_fundamental_or_enum<int (D::*)()const>::value << '\n';
    
        cout << "is_mem_data_ptr\t" << '\t';
        cout << is_mem_data_ptr<int>::value << '\t';
        cout << is_mem_data_ptr<int&>::value << '\t';
        cout << is_mem_data_ptr<int&&>::value << '\t';
        cout << is_mem_data_ptr<int[6]>::value << '\t';
        cout << is_mem_data_ptr<int*>::value << '\t';
        cout << is_mem_data_ptr<int()>::value << '\t';
        cout << is_mem_data_ptr<int(*)()>::value << '\t';
        cout << is_mem_data_ptr<int(&)()>::value << '\t';
        cout << is_mem_data_ptr<A>::value << '\t';
        cout << is_mem_data_ptr<B>::value << '\t';
        cout << is_mem_data_ptr<C>::value << '\t';
        cout << is_mem_data_ptr<D>::value << '\t';
        cout << is_mem_data_ptr<int D::*>::value << '\t';
        cout << is_mem_data_ptr<int (D::*)()>::value << '\t';
        cout << is_mem_data_ptr<int (D::*)()const>::value << '\n';
    
        cout << "is_mem_fun_ptr\t" << '\t';
        cout << is_mem_fun_ptr<int>::value << '\t';
        cout << is_mem_fun_ptr<int&>::value << '\t';
        cout << is_mem_fun_ptr<int&&>::value << '\t';
        cout << is_mem_fun_ptr<int[6]>::value << '\t';
        cout << is_mem_fun_ptr<int*>::value << '\t';
        cout << is_mem_fun_ptr<int()>::value << '\t';
        cout << is_mem_fun_ptr<int(*)()>::value << '\t';
        cout << is_mem_fun_ptr<int(&)()>::value << '\t';
        cout << is_mem_fun_ptr<A>::value << '\t';
        cout << is_mem_fun_ptr<B>::value << '\t';
        cout << is_mem_fun_ptr<C>::value << '\t';
        cout << is_mem_fun_ptr<D>::value << '\t';
        cout << is_mem_fun_ptr<int D::*>::value << '\t';
        cout << is_mem_fun_ptr<int (D::*)()>::value << '\t';
        cout << is_mem_fun_ptr<int (D::*)()const>::value << '\n';
    }
    

    sollte funktionieren (rvalue-Rereferenzen bei alten Compilern weglassen).


  • Mod

    Nochmal ein bisschen überarbeitet. Diese Version funktioniert mindestens ab gcc 3.4, Comeau-C++ und clang 3.1 sind auch zufrieden.
    rvalue-Referenzen und scoped enums werden unterstützt, es werden aber keine C++11-Features verwendet. Es sollte auch mit extended integer Typen funktionieren, allerdings kann ich das nicht testen.
    Was sagt Visual C++ dazu?

    #include <cstddef>
    
    template <bool b> struct bool_ { static const bool value = b; };
    template <typename T> struct not_ { static const bool value = !T::value; };
    typedef bool_<true> true_type;
    typedef bool_<false> false_type;
    
    template <typename T> struct identity { typedef T type; };
    
    template <typename T> struct is_void;
    template <typename T> struct is_array;
    template <typename T, bool = is_void<T>::value || is_array<T>::value> struct is_reference;
    template <typename T> struct is_class;
    
    // transformations
    template <typename T, bool = is_void<T>::value> struct add_reference : identity<T&> {};
    template <typename T, bool b> struct add_reference<T&, b> : identity<T&> {};
    template <typename T> struct add_reference<T, true> : identity<T> {};
    
    template <typename T, bool = is_void<T>::value> struct remove_reference : remove_reference<typename add_reference<T>::type> {};
    template <typename T, bool b> struct remove_reference<T&, b> : identity<T> {};
    template <typename T> struct remove_reference<T, true> : identity<T> {};
    
    template <typename T> struct remove_const : identity<T> {};
    template <typename T> struct remove_const<const T> : identity<T> {};
    
    template <typename T> struct remove_volatile : identity<T> {};
    template <typename T> struct remove_volatile<volatile T> : identity<T> {};
    
    template <typename T> struct remove_cv : remove_volatile<typename remove_const<T>::type> {};
    
    // relations
    template <typename T, typename U> struct is_same : false_type {};
    template <typename T> struct is_same<T, T> : true_type {};
    
    template <typename T, typename U, bool = is_void<T>::value> struct is_convertible
    {
        static typename add_reference<T>::type makeT();
        typedef char& yes_type;
        typedef char (&no_type)[2];
        template <typename V> static no_type test(...);
        template <typename V> static yes_type test(V);
        static const bool value = sizeof test<U>(makeT()) == sizeof(yes_type);
    };
    template <typename T, typename U> struct is_convertible<T[], U, false> : is_convertible<T*, U, false> {};
    template <typename T, std::size_t N, typename U> struct is_convertible<T[N], U, false> : is_convertible<T*, U, false> {};
    template <typename T, typename U> struct is_convertible<T, U, true> : is_void<U> {};
    
    // predicates
    template <typename T> struct is_void : is_same<typename remove_cv<T>::type, void> {};
    
    template <typename T> struct is_arithmetic : bool_<!is_class<T>::value && !is_reference<T>::value && is_convertible<T, int>::value && is_convertible<int, T>::value> {};
    
    template <typename T> struct is_fundamental: bool_<is_arithmetic<T>::value || is_void<T>::value> {};
    
    template <typename T> struct is_array : false_type {};
    template <typename T> struct is_array<T[]> : true_type {};
    template <typename T, std::size_t N> struct is_array<T[N]> : true_type {};
    
    template <typename T, bool = !is_void<T>::value && !is_reference<T>::value && !is_array<T>::value> struct is_function : is_same<void(T),void(T*)> {};
    template <typename T> struct is_function<T, false> : false_type {};
    
    template <typename T> struct is_object : bool_<!is_void<T>::value && !is_reference<T>::value && !is_function<T>::value> {};
    
    template <typename T> struct is_pointer : false_type {};
    template <typename T> struct is_pointer<T*> : true_type {};
    
    template <typename T, bool> struct is_reference : not_<is_same<T, typename remove_reference<typename add_reference<T>::type>::type> > {};
    template <typename T> struct is_reference<T, true> : false_type {};
    
    template <typename T> struct is_class
    {
        typedef char& yes_type;
        typedef char (&no_type)[2];
        template <typename U> static no_type test(...);
        template <typename U> static yes_type test(int U::*);
        static const bool value = sizeof test<T>(0) == sizeof(yes_type);
    };
    
    template <typename T> struct is_unscoped_enum : bool_<is_object<T>::value && !is_fundamental<T>::value && !is_class<T>::value && is_convertible<T, int>::value> {};
    
    template <typename T, bool = is_object<T>::value && !is_class<T>::value && !is_fundamental<T>::value && !is_array<T>::value
                                 && !is_pointer<T>::value && !is_unscoped_enum<T>::value>
    struct is_scoped_enum : not_<is_convertible<T, bool> > {};
    template <typename T> struct is_scoped_enum<T, false> : false_type {};
    
    template <typename T> struct is_enum : bool_<is_unscoped_enum<T>::value || is_scoped_enum<T>::value> {};
    
    template <typename T> struct is_mem_data_ptr : false_type {};
    template <typename T, typename C> struct is_mem_data_ptr<T C::*> : is_object<typename remove_reference<T>::type> {};
    
    template <typename T> struct is_mem_fun_ptr : bool_<is_object<T>::value && !is_class<T>::value && !is_fundamental<T>::value && !is_array<T>::value
    						    && !is_pointer<T>::value && !is_enum<T>::value && !is_mem_data_ptr<T>::value> {};
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    template <bool b> struct assertion_failure;
    template <> struct assertion_failure<true> : true_type {};
    
    #define FUSE( x, y ) x##y
    #define STATIC_ASSERT( T, x, v ) typedef int FUSE( assert, __LINE__ ) [sizeof(assertion_failure<T<x>::value==v>::value)]
    
    typedef int arithmetic_type;
    typedef void void_type;
    typedef int& lref_type;
    typedef int array_type[42];
    typedef int array_type2[];
    typedef int***** pointer_type;
    typedef int fun_type();
    typedef int(*pfun_type)();
    typedef int(&fun_ref_type)();
    enum enum_type {};
    struct struct_type {};
    union union_type {};
    typedef enum_type (struct_type::*mem_data_ptr_type_helper)() const;
    typedef mem_data_ptr_type_helper struct_type::*mem_data_ptr_type;
    typedef enum_type (struct_type::*mem_fun_ptr_type_)();
    typedef mem_data_ptr_type (struct_type::*mem_fun_ptr_type)() const;
    typedef mem_fun_ptr_type_ (struct_type::*mem_fun_ptr_type2)() const;
    
    #ifdef WITHCPP11
    enum class enum_class_type {};
    #define ENUM_CLASS_IS_SCOPED true
    typedef int&& rref_type;
    #else
    enum enum_class_type {};
    #define ENUM_CLASS_IS_SCOPED false
    typedef int& rref_type;
    #endif
    
    int main()
    {
        STATIC_ASSERT( is_class, arithmetic_type,   false );
        STATIC_ASSERT( is_class, void_type,         false );
        STATIC_ASSERT( is_class, lref_type,         false );
        STATIC_ASSERT( is_class, rref_type,         false );
        STATIC_ASSERT( is_class, array_type,        false );
        STATIC_ASSERT( is_class, array_type2,       false );
        STATIC_ASSERT( is_class, pointer_type,      false );
        STATIC_ASSERT( is_class, fun_type,          false );
        STATIC_ASSERT( is_class, pfun_type,         false );
        STATIC_ASSERT( is_class, fun_ref_type,      false );
        STATIC_ASSERT( is_class, enum_type,         false );
        STATIC_ASSERT( is_class, enum_class_type,   false );
        STATIC_ASSERT( is_class, struct_type,       true );
        STATIC_ASSERT( is_class, union_type,        true );
        STATIC_ASSERT( is_class, mem_data_ptr_type, false );
        STATIC_ASSERT( is_class, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_class, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_arithmetic, arithmetic_type,   true );
        STATIC_ASSERT( is_arithmetic, void_type,         false );
        STATIC_ASSERT( is_arithmetic, lref_type,         false );
        STATIC_ASSERT( is_arithmetic, rref_type,         false );
        STATIC_ASSERT( is_arithmetic, array_type,        false );
        STATIC_ASSERT( is_arithmetic, array_type2,       false );
        STATIC_ASSERT( is_arithmetic, pointer_type,      false );
        STATIC_ASSERT( is_arithmetic, fun_type,          false );
        STATIC_ASSERT( is_arithmetic, pfun_type,         false );
        STATIC_ASSERT( is_arithmetic, fun_ref_type,      false );
        STATIC_ASSERT( is_arithmetic, enum_type,         false );
        STATIC_ASSERT( is_arithmetic, enum_class_type,   false );
        STATIC_ASSERT( is_arithmetic, struct_type,       false);
        STATIC_ASSERT( is_arithmetic, union_type,        false);
        STATIC_ASSERT( is_arithmetic, mem_data_ptr_type, false );
        STATIC_ASSERT( is_arithmetic, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_arithmetic, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_void, arithmetic_type,   false );
        STATIC_ASSERT( is_void, void_type,         true );
        STATIC_ASSERT( is_void, lref_type,         false );
        STATIC_ASSERT( is_void, rref_type,         false );
        STATIC_ASSERT( is_void, array_type,        false );
        STATIC_ASSERT( is_void, array_type2,       false );
        STATIC_ASSERT( is_void, pointer_type,      false );
        STATIC_ASSERT( is_void, fun_type,          false );
        STATIC_ASSERT( is_void, pfun_type,         false );
        STATIC_ASSERT( is_void, fun_ref_type,      false );
        STATIC_ASSERT( is_void, enum_type,         false );
        STATIC_ASSERT( is_void, enum_class_type,   false );
        STATIC_ASSERT( is_void, struct_type,       false );
        STATIC_ASSERT( is_void, union_type,        false );
        STATIC_ASSERT( is_void, mem_data_ptr_type, false );
        STATIC_ASSERT( is_void, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_void, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_fundamental, arithmetic_type,   true );
        STATIC_ASSERT( is_fundamental, void_type,         true );
        STATIC_ASSERT( is_fundamental, lref_type,         false );
        STATIC_ASSERT( is_fundamental, rref_type,         false );
        STATIC_ASSERT( is_fundamental, array_type,        false );
        STATIC_ASSERT( is_fundamental, array_type2,       false );
        STATIC_ASSERT( is_fundamental, pointer_type,      false );
        STATIC_ASSERT( is_fundamental, fun_type,          false );
        STATIC_ASSERT( is_fundamental, pfun_type,         false );
        STATIC_ASSERT( is_fundamental, fun_ref_type,      false );
        STATIC_ASSERT( is_fundamental, enum_type,         false );
        STATIC_ASSERT( is_fundamental, enum_class_type,   false );
        STATIC_ASSERT( is_fundamental, struct_type,       false );
        STATIC_ASSERT( is_fundamental, union_type,        false );
        STATIC_ASSERT( is_fundamental, mem_data_ptr_type, false );
        STATIC_ASSERT( is_fundamental, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_fundamental, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_array, arithmetic_type,   false );
        STATIC_ASSERT( is_array, void_type,         false );
        STATIC_ASSERT( is_array, lref_type,         false );
        STATIC_ASSERT( is_array, rref_type,         false );
        STATIC_ASSERT( is_array, array_type,        true );
        STATIC_ASSERT( is_array, array_type2,       true );
        STATIC_ASSERT( is_array, pointer_type,      false );
        STATIC_ASSERT( is_array, fun_type,          false );
        STATIC_ASSERT( is_array, pfun_type,         false );
        STATIC_ASSERT( is_array, fun_ref_type,      false );
        STATIC_ASSERT( is_array, enum_type,         false );
        STATIC_ASSERT( is_array, enum_class_type,   false );
        STATIC_ASSERT( is_array, struct_type,       false );
        STATIC_ASSERT( is_array, union_type,        false );
        STATIC_ASSERT( is_array, mem_data_ptr_type, false );
        STATIC_ASSERT( is_array, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_array, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_reference, arithmetic_type,   false );
        STATIC_ASSERT( is_reference, void_type,         false );
        STATIC_ASSERT( is_reference, lref_type,         true );
        STATIC_ASSERT( is_reference, rref_type,         true );
        STATIC_ASSERT( is_reference, array_type,        false );
        STATIC_ASSERT( is_reference, array_type2,       false );
        STATIC_ASSERT( is_reference, pointer_type,      false );
        STATIC_ASSERT( is_reference, fun_type,          false );
        STATIC_ASSERT( is_reference, pfun_type,         false );
        STATIC_ASSERT( is_reference, fun_ref_type,      true );
        STATIC_ASSERT( is_reference, enum_type,         false );
        STATIC_ASSERT( is_reference, enum_class_type,   false );
        STATIC_ASSERT( is_reference, struct_type,       false );
        STATIC_ASSERT( is_reference, union_type,        false );
        STATIC_ASSERT( is_reference, mem_data_ptr_type, false );
        STATIC_ASSERT( is_reference, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_reference, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_pointer, arithmetic_type,   false );
        STATIC_ASSERT( is_pointer, void_type,         false );
        STATIC_ASSERT( is_pointer, lref_type,         false );
        STATIC_ASSERT( is_pointer, rref_type,         false );
        STATIC_ASSERT( is_pointer, array_type,        false );
        STATIC_ASSERT( is_pointer, array_type2,       false );
        STATIC_ASSERT( is_pointer, pointer_type,      true );
        STATIC_ASSERT( is_pointer, fun_type,          false );
        STATIC_ASSERT( is_pointer, pfun_type,         true );
        STATIC_ASSERT( is_pointer, fun_ref_type,      false );
        STATIC_ASSERT( is_pointer, enum_type,         false );
        STATIC_ASSERT( is_pointer, enum_class_type,   false );
        STATIC_ASSERT( is_pointer, struct_type,       false );
        STATIC_ASSERT( is_pointer, union_type,        false );
        STATIC_ASSERT( is_pointer, mem_data_ptr_type, false );
        STATIC_ASSERT( is_pointer, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_pointer, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_object, arithmetic_type,   true );
        STATIC_ASSERT( is_object, void_type,         false );
        STATIC_ASSERT( is_object, lref_type,         false );
        STATIC_ASSERT( is_object, rref_type,         false );
        STATIC_ASSERT( is_object, array_type,        true );
        STATIC_ASSERT( is_object, array_type2,       true );
        STATIC_ASSERT( is_object, pointer_type,      true );
        STATIC_ASSERT( is_object, fun_type,          false );
        STATIC_ASSERT( is_object, pfun_type,         true );
        STATIC_ASSERT( is_object, fun_ref_type,      false );
        STATIC_ASSERT( is_object, enum_type,         true );
        STATIC_ASSERT( is_object, enum_class_type,   true );
        STATIC_ASSERT( is_object, struct_type,       true );
        STATIC_ASSERT( is_object, union_type,        true );
        STATIC_ASSERT( is_object, mem_data_ptr_type, true );
        STATIC_ASSERT( is_object, mem_fun_ptr_type,  true );
        STATIC_ASSERT( is_object, mem_fun_ptr_type2, true );
    
        STATIC_ASSERT( is_function, arithmetic_type,   false );
        STATIC_ASSERT( is_function, void_type,         false );
        STATIC_ASSERT( is_function, lref_type,         false );
        STATIC_ASSERT( is_function, rref_type,         false );
        STATIC_ASSERT( is_function, array_type,        false );
        STATIC_ASSERT( is_function, array_type2,       false );
        STATIC_ASSERT( is_function, pointer_type,      false );
        STATIC_ASSERT( is_function, fun_type,          true );
        STATIC_ASSERT( is_function, pfun_type,         false );
        STATIC_ASSERT( is_function, fun_ref_type,      false );
        STATIC_ASSERT( is_function, enum_type,         false );
        STATIC_ASSERT( is_function, enum_class_type,   false );
        STATIC_ASSERT( is_function, struct_type,       false );
        STATIC_ASSERT( is_function, union_type,        false );
        STATIC_ASSERT( is_function, mem_data_ptr_type, false );
        STATIC_ASSERT( is_function, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_function, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_unscoped_enum, arithmetic_type,   false );
        STATIC_ASSERT( is_unscoped_enum, void_type,         false );
        STATIC_ASSERT( is_unscoped_enum, lref_type,         false );
        STATIC_ASSERT( is_unscoped_enum, rref_type,         false );
        STATIC_ASSERT( is_unscoped_enum, array_type,        false );
        STATIC_ASSERT( is_unscoped_enum, array_type2,       false );
        STATIC_ASSERT( is_unscoped_enum, pointer_type,      false );
        STATIC_ASSERT( is_unscoped_enum, fun_type,          false );
        STATIC_ASSERT( is_unscoped_enum, pfun_type,         false );
        STATIC_ASSERT( is_unscoped_enum, fun_ref_type,      false );
        STATIC_ASSERT( is_unscoped_enum, enum_type,         true );
        STATIC_ASSERT( is_unscoped_enum, enum_class_type,   !ENUM_CLASS_IS_SCOPED );
        STATIC_ASSERT( is_unscoped_enum, struct_type,       false );
        STATIC_ASSERT( is_unscoped_enum, union_type,        false );
        STATIC_ASSERT( is_unscoped_enum, mem_data_ptr_type, false );
        STATIC_ASSERT( is_unscoped_enum, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_unscoped_enum, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_scoped_enum, arithmetic_type,   false );
        STATIC_ASSERT( is_scoped_enum, void_type,         false );
        STATIC_ASSERT( is_scoped_enum, lref_type,         false );
        STATIC_ASSERT( is_scoped_enum, rref_type,         false );
        STATIC_ASSERT( is_scoped_enum, array_type,        false );
        STATIC_ASSERT( is_scoped_enum, array_type2,       false );
        STATIC_ASSERT( is_scoped_enum, pointer_type,      false );
        STATIC_ASSERT( is_scoped_enum, fun_type,          false );
        STATIC_ASSERT( is_scoped_enum, pfun_type,         false );
        STATIC_ASSERT( is_scoped_enum, fun_ref_type,      false );
        STATIC_ASSERT( is_scoped_enum, enum_type,         false );
        STATIC_ASSERT( is_scoped_enum, enum_class_type,   ENUM_CLASS_IS_SCOPED );
        STATIC_ASSERT( is_scoped_enum, struct_type,       false );
        STATIC_ASSERT( is_scoped_enum, union_type,        false );
        STATIC_ASSERT( is_scoped_enum, mem_data_ptr_type, false );
        STATIC_ASSERT( is_scoped_enum, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_scoped_enum, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_enum, arithmetic_type,   false );
        STATIC_ASSERT( is_enum, void_type,         false );
        STATIC_ASSERT( is_enum, lref_type,         false );
        STATIC_ASSERT( is_enum, rref_type,         false );
        STATIC_ASSERT( is_enum, array_type,        false );
        STATIC_ASSERT( is_enum, array_type2,       false );
        STATIC_ASSERT( is_enum, pointer_type,      false );
        STATIC_ASSERT( is_enum, fun_type,          false );
        STATIC_ASSERT( is_enum, pfun_type,         false );
        STATIC_ASSERT( is_enum, fun_ref_type,      false );
        STATIC_ASSERT( is_enum, enum_type,         true );
        STATIC_ASSERT( is_enum, enum_class_type,   true );
        STATIC_ASSERT( is_enum, struct_type,       false );
        STATIC_ASSERT( is_enum, union_type,        false );
        STATIC_ASSERT( is_enum, mem_data_ptr_type, false );
        STATIC_ASSERT( is_enum, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_enum, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_mem_data_ptr, arithmetic_type,   false );
        STATIC_ASSERT( is_mem_data_ptr, void_type,         false );
        STATIC_ASSERT( is_mem_data_ptr, lref_type,         false );
        STATIC_ASSERT( is_mem_data_ptr, rref_type,         false );
        STATIC_ASSERT( is_mem_data_ptr, array_type,        false );
        STATIC_ASSERT( is_mem_data_ptr, array_type2,       false );
        STATIC_ASSERT( is_mem_data_ptr, pointer_type,      false );
        STATIC_ASSERT( is_mem_data_ptr, fun_type,          false );
        STATIC_ASSERT( is_mem_data_ptr, pfun_type,         false );
        STATIC_ASSERT( is_mem_data_ptr, fun_ref_type,      false );
        STATIC_ASSERT( is_mem_data_ptr, enum_type,         false );
        STATIC_ASSERT( is_mem_data_ptr, enum_class_type,   false );
        STATIC_ASSERT( is_mem_data_ptr, struct_type,       false );
        STATIC_ASSERT( is_mem_data_ptr, union_type,        false );
        STATIC_ASSERT( is_mem_data_ptr, mem_data_ptr_type, true );
        STATIC_ASSERT( is_mem_data_ptr, mem_fun_ptr_type,  false );
        STATIC_ASSERT( is_mem_data_ptr, mem_fun_ptr_type2, false );
    
        STATIC_ASSERT( is_mem_fun_ptr, arithmetic_type,   false );
        STATIC_ASSERT( is_mem_fun_ptr, void_type,         false );
        STATIC_ASSERT( is_mem_fun_ptr, lref_type,         false );
        STATIC_ASSERT( is_mem_fun_ptr, rref_type,         false );
        STATIC_ASSERT( is_mem_fun_ptr, array_type,        false );
        STATIC_ASSERT( is_mem_fun_ptr, array_type2,       false );
        STATIC_ASSERT( is_mem_fun_ptr, pointer_type,      false );
        STATIC_ASSERT( is_mem_fun_ptr, fun_type,          false );
        STATIC_ASSERT( is_mem_fun_ptr, pfun_type,         false );
        STATIC_ASSERT( is_mem_fun_ptr, fun_ref_type,      false );
        STATIC_ASSERT( is_mem_fun_ptr, enum_type,         false );
        STATIC_ASSERT( is_mem_fun_ptr, enum_class_type,   false );
        STATIC_ASSERT( is_mem_fun_ptr, struct_type,       false );
        STATIC_ASSERT( is_mem_fun_ptr, union_type,        false );
        STATIC_ASSERT( is_mem_fun_ptr, mem_data_ptr_type, false );
        STATIC_ASSERT( is_mem_fun_ptr, mem_fun_ptr_type,  true );
        STATIC_ASSERT( is_mem_fun_ptr, mem_fun_ptr_type2, true );
    }
    


  • VS 10 mag den Code nicht so sehr:

    Microsoft (R) 32-Bit C/C++-Optimierungscompiler Version 16.00.40219.01 für 80x86
    Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.
    
    memfn.cpp
    memfn.cpp(15) : error C2265: 'T': Verweis auf ein Array der Größe Null ist ungültig
            memfn.cpp(63): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "add_reference<T>".
            with
            [
                T=array_type2 
            ]
            memfn.cpp(49): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "is_reference<T>".
            with
            [
                T=array_type2 
            ]
            memfn.cpp(142): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "is_arithmetic<T>".
            with
            [
                T=array_type2
            ]
    memfn.cpp(214) : error C2027: Verwendung des undefinierten Typs "assertion_failure<b>"
            with
            [
                b=false
            ]
    memfn.cpp(214) : error C2065: 'value': nichtdeklarierter Bezeichner
    memfn.cpp(214) : error C2070: ''unknown-type'': Ungültiger sizeof-Operand
    memfn.cpp(214) : error C2466: Zuordnung eines Arrays der konstanten Größe 0 nicht möglich.
    memfn.cpp(214) : error C2086: 'int assert__LINE__[1]': Neudefinition
            memfn.cpp(119): Siehe Deklaration von 'assert__LINE__'
    memfn.cpp(332) : error C2027: Verwendung des undefinierten Typs "assertion_failure<b>"
            with
            [
                b=false
            ]
    memfn.cpp(332) : error C2065: 'value': nichtdeklarierter Bezeichner
    memfn.cpp(332) : error C2070: ''unknown-type'': Ungültiger sizeof-Operand
    memfn.cpp(332) : error C2466: Zuordnung eines Arrays der konstanten Größe 0 nicht möglich.
    memfn.cpp(332) : error C2086: 'int assert__LINE__[1]': Neudefinition
            memfn.cpp(119): Siehe Deklaration von 'assert__LINE__'
    memfn.cpp(350) : error C2027: Verwendung des undefinierten Typs "assertion_failure<b>"
            with
            [
                b=false
            ]
    memfn.cpp(350) : error C2065: 'value': nichtdeklarierter Bezeichner
    memfn.cpp(350) : error C2070: ''unknown-type'': Ungültiger sizeof-Operand
    memfn.cpp(350) : error C2466: Zuordnung eines Arrays der konstanten Größe 0 nicht möglich.
    memfn.cpp(350) : error C2086: 'int assert__LINE__[1]': Neudefinition
            memfn.cpp(119): Siehe Deklaration von 'assert__LINE__'
    

  • Mod

    Etwas geändert, um den ersten Fehler zu beseitigen.
    Edit: noch ein paar probleme mit g++ 4.0-4.3 beseitigt (getestet mit 3.4.6, 4.0.4, 4.1.2, 4.2.4, 4.3.6, 4.4.6, 4.5.3, 4.6.3, 4.7.1, 4.8.0 alpha). g++ 3.3.6 kommt offenbar nicht mit dem SFINAE-Trick zurecht.
    Die Logik bei Zeigern auf Member wurde geändert. Jetzt funktioniert es vermutlich auch mit vc2010.



  • Okay, kompiliert jetzt auch unter VS 2008:
    aber mit warnungen:

    STATIC_ASSERT( is_scoped_enum, arithmetic_type,   false );
    

    ..\..\..\..\Project\src\Main\Main.cpp(225) : warning C4800: 'arithmetic_type' : forcing value to bool 'true' or 'false' (performance warning)
    1> ..\..\..\..\Project\src\Main\Main.cpp(267) : see reference to class template instantiation 'is_convertible<T,U>' being compiled
    1> with
    1> [
    1> T=arithmetic_type,
    1> U=bool
    1> ]
    1> ..\..\..\..\Project\src\Main\Main.cpp(470) : see reference to class template instantiation 'is_scoped_enum<T>' being compiled
    1> with
    1> [
    1> T=arithmetic_type
    1> ]
    1>..\..\..\..\Project\src\Main\Main.cpp(225) : warning C4800: 'arithmetic_type' : forcing value to bool 'true' or 'false' (performance warning)
    1> ..\..\..\..\Project\src\Main\Main.cpp(267) : see reference to class template instantiation 'is_convertible<T,U>' being compiled
    1> with
    1> [
    1> T=lref_type ,
    1> U=bool
    1> ]
    1> ..\..\..\..\Project\src\Main\Main.cpp(472) : see reference to class template instantiation 'is_scoped_enum<T>' being compiled
    1> with
    1> [
    1> T=lref_type
    1> ]


  • Mod

    Bitte noch mal mit der aktuellen Version probieren.



  • Ich hatte meine letzte message editiert, die Warnungen hast du gesehen?

    aber hey, sieht nicht schlecht aus, ist das ein kompletter type_traits ersatz für C++03?

    Was mir so btw. auffällt ist, das du glaube keine compound typen behandelst,
    also z.B.

    int**** foo;
    

    In dem Buch löst er das dadurch, das er das template immer wieder mit sich selbst aufruft.



  • Nash26 schrieb:

    Was mir so btw. auffällt ist, das du glaube keine compound typen behandelst,
    also z.B.

    int**** foo;
    

    Ohne näher Bezug zum Code zu nehmen, sei hier angemerkt, dass das auch "nur" ein Zeiger ist.


  • Mod

    Nash26 schrieb:

    Ich hatte meine letzte message editiert, die Warnungen hast du gesehen?

    aber hey, sieht nicht schlecht aus, ist das ein kompletter type_traits ersatz für C++03?

    Was mir so btw. auffällt ist, das du glaube keine compound typen behandelst,
    also z.B.

    int**** foo;
    

    In dem Buch löst er das dadurch, das er das template immer wieder mit sich selbst aufruft.

    Die Warnung ist harmlos, ich habe aber den Code nochmal geändert, das sollte jetzt ohne diese Warnung compilieren.

    Ich habe auch noch mal die Erkennung von Zeigern auf Member geändert, der Workaround zuvor war falsch. Hoffentlich funktioniert das weiterhin mit Visual C++ 2010.
    G++ 4.0-4.3 zerlegt Zeiger auf konstante Memberfunktionen in eine Referenz und den Klassenbezug (und hoffentlich ist das auch das Problem bei Visual C++ 2010, dann funktiniert der Workaround). Indem ich jetzt dort (Zeile 92) die Referenz entferne (die dort eigentlich nie auftreten kann, denn Zeiger auf Member verweisen niemals auf Referenzen), funktioniert es jetzt wieder mit allen g++-Versionen ab 3.4.

    Ich habe auch den Test auf int***** eingebaut (deshalb die vielen typedefs, um leicht mit verschiedenen Typen spielen zu können). Eine rekursive Behandlung ist in der Regel nicht erforderlich.



  • STATIC_ASSERT( is_function, fun_type,          true );
    

    ..\..\..\..\Project\src\Main\Main.cpp(449) : error C2027: use of undefined type 'assertion_failure<b>'
    1> with
    1> [
    1> b=false
    1> ]
    1>..\..\..\..\Project\src\Main\Main.cpp(449) : error C2065: 'value' : undeclared identifier
    1>..\..\..\..\Project\src\Main\Main.cpp(449) : error C2070: ''unknown-type'': illegal sizeof operand
    1>..\..\..\..\Project\src\Main\Main.cpp(449) : error C2466: cannot allocate an array of constant size 0
    1>..\..\..\..\Project\src\Main\Main.cpp(449) : error C2086: 'int assert__LINE__[1]' : redefinition
    1> ..\..\..\..\Project\src\Main\Main.cpp(316) : see declaration of 'assert__LINE__'
    1>..\..\..\..\Project\src\Main\Main.cpp(224) : warning C4800: 'fun_type (__cdecl *)' : forcing value to bool 'true' or 'false' (performance warning)
    1> ..\..\..\..\Project\src\Main\Main.cpp(185) : see reference to class template instantiation 'is_convertible<T,U>' being compiled
    1> with
    1> [
    1> T=fun_type ,
    1> U=bool
    1> ]
    1> ..\..\..\..\Project\src\Main\Main.cpp(267) : see reference to class template instantiation 'not_<T>' being compiled
    1> with
    1> [
    1> T=is_convertible<fun_type ,bool>
    1> ]
    1> ..\..\..\..\Project\src\Main\Main.cpp(485) : see reference to class template instantiation 'is_scoped_enum<T>' being compiled
    1> with
    1> [
    1> T=fun_type
    1> ]
    1>..\..\..\..\Project\src\Main\Main.cpp(539) : error C2027: use of undefined type 'assertion_failure<b>'
    1> with
    1> [
    1> b=false
    1> ]


  • Mod

    Fehler in is_object behoben. Bitte noch mal testen, mit und ohne Compilererweiterungen.



  • 1>  main.cpp
    1>main.cpp(266): error C2027: use of undefined type 'assertion_failure<b>'
    1>          with
    1>          [
    1>              b=false
    1>          ]
    1>main.cpp(266): error C2065: 'value' : undeclared identifier
    1>main.cpp(266): error C2070: ''unknown-type'': illegal sizeof operand
    1>main.cpp(266): error C2466: cannot allocate an array of constant size 0
    1>main.cpp(266): error C2086: 'int assert__LINE__[1]' : redefinition
    1>          main.cpp(133) : see declaration of 'assert__LINE__'
    1>main.cpp(284): error C2027: use of undefined type 'assertion_failure<b>'
    1>          with
    1>          [
    1>              b=false
    1>          ]
    1>main.cpp(284): error C2065: 'value' : undeclared identifier
    1>main.cpp(284): error C2070: ''unknown-type'': illegal sizeof operand
    1>main.cpp(284): error C2466: cannot allocate an array of constant size 0
    1>main.cpp(284): error C2086: 'int assert__LINE__[1]' : redefinition
    1>          main.cpp(133) : see declaration of 'assert__LINE__'
    1>main.cpp(43): warning C4800: 'fun_type (__cdecl *)' : forcing value to bool 'true' or 'false' (performance warning)
    1>          main.cpp(4) : see reference to class template instantiation 'is_convertible<T,U>' being compiled
    1>          with
    1>          [
    1>              T=fun_type ,
    1>              U=bool
    1>          ]
    1>          main.cpp(85) : see reference to class template instantiation 'not_<T>' being compiled
    1>          with
    1>          [
    1>              T=is_convertible<fun_type ,bool>
    1>          ]
    1>          main.cpp(320) : see reference to class template instantiation 'is_scoped_enum<T>' being compiled
    1>          with
    1>          [
    1>              T=fun_type
    1>          ]
    1>main.cpp(374): error C2027: use of undefined type 'assertion_failure<b>'
    1>          with
    1>          [
    1>              b=false
    1>          ]
    1>main.cpp(374): error C2065: 'value' : undeclared identifier
    1>main.cpp(374): error C2070: ''unknown-type'': illegal sizeof operand
    1>main.cpp(374): error C2466: cannot allocate an array of constant size 0
    1>main.cpp(374): error C2086: 'int assert__LINE__[1]' : redefinition
    1>          main.cpp(133) : see declaration of 'assert__LINE__'
    1>
    1>Build FAILED.
    

    Ohne Compilererweiterungen geht's.


Anmelden zum Antworten