HAS_MEMBER macro



  • Hi,
    gerade im Zusammenhang mit static_assert und Templates wäre ein HAS_MEMBER Template/Macro oft sehr sinvoll. Deswegen habe ich mir folgendes überlegt:

    #define DETAIL_DEF_HAS_MEMBER(type, x)					\
      struct HasMember {						\
        static auto check(float) -> decltype(&type::x);		\
        static void check(int);					\
      };                        
    
    #define HAS_MEMBER(type, mem) ([=]() -> bool { DETAIL_DEF_HAS_MEMBER(type, mem); return !std::is_same<decltype(HasMember::check(1.0f) ), void>::value; })()
    

    Es scheint auch zu funktionieren (ich kenne mich mit Macros nicht so gut aus), allerdings frage ich mich, ob das auch ohne Macros geht, oder ob es vlt. schon so etwas in der Art in Boost gibt (ich habe nichts gefunden). Kennt ihr eine solche Funktion in Boost oder wisst ihr, ob das auch ohne Macros geht?

    EDIT: Habe es gerade noch mal getestet: Es funktioniert leider nur wenn die Memberfunktion existiert, sonst nicht :(. Hat jemand eine Idee, um das zu beheben? (Es kommt ein Compiler Error: Fehler: Y ist kein Element von 😵



  • Das Beispiel hier funktioniert schonmal solange der Member nicht private ist:

    struct MemberTest
    {
        template<typename T> static auto test(T *) -> decltype(&T::x);
        static void test(...);
    };
    
    #define HAS_X(type) (!std::is_same<decltype(MemberTest::test((type *) 0)), void>::value)
    


  • Ja ich weiß, bloß ich möchte das ganze gerne ohne das man ein HAS_X, ein HAS_Y, ein HAS_Z, ein HAS_... schreiben muss.



  • pyhax schrieb:

    Ja ich weiß, bloß ich möchte das ganze gerne ohne das man ein HAS_X, ein HAS_Y, ein HAS_Z, ein HAS_... schreiben muss.

    Das hab ich bloß weggelassen, du kannst ja dein Define wieder reinmachen. (Oder liegt der Fehler gerade dort?)

    EDIT: Moment, ich schau mal nach...
    EDIT2: Nein, wenn du meinen Code statt deinem noch reindefinierst, sollte es funktionieren. Das Problem ist, dass der Compiler durch dein #define ohne template-check-Funktion meint "Das wird nie funktionieren", wohingegen er bei einer template-check-Funktion halt nur sieht "Ok, bei diesem Typ klappts nicht, also nehmen wir die andere".



  • Leider geht das nicht:

    #include <iostream>
    
    #define DEF_HAS_MEMBER(x)						\
      struct HasMember {							\
        template <class T>							\
        static auto check(float) -> decltype(&T::x);			\
        template <class T>							\
        static auto check(int) -> void;					\
      };                        
    
    #define HAS_MEMBER(type, mem) ([=]() -> bool { DEF_HAS_MEMBER(mem); return !std::is_same<decltype(HasMember::check<type>(1.0f) ), void>::value; })()
    
    class X {
      public:
        void Y() {}
    };
    
    int main() {
      std::cout << HAS_MEMBER(X, Y) << std::endl;
    }
    

    Fehler: ungültige Deklaration eines Elementtemplates in lokaler Klasse


Anmelden zum Antworten