Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   

Die mobilen Seiten von c++.de:
http://m.c-plusplus.de
Infos hier [BETA]

  
c++.de :: C++ (auch C++0x und C++11) ::  Check für is member function pointer  
Gehen Sie zu Seite 1, 2, 3, 4  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
Nash26
Mitglied

Benutzerprofil
Anmeldungsdatum: 12.10.2009
Beiträge: 32
Beitrag Nash26 Mitglied 20:59:23 08.08.2012   Titel:   Check für is member function pointer            Zitieren

Hi zusammen,

ich suche einen Methode mit der ich überprüfen kann ob ein Type T ein Member function ptr is oder nicht.

also sowas in der form
is_member_function_ptr<void (MyClass::*)(void)>::value => true
is_member_function_ptr<void (*)(int)>::value => false da function

Das ganze muss mit C++03 funktionieren, VS + gcc
Boost kann ich leider nicht verwenden.

Hat jemand ne idee?
Das ich SFINAE verwenden muss ist klar, aber ich möchte ungern eine substitution für alle mögliche argument variationen niederschreiben.
Was denkt ihr?
arogmyxdfa
Unregistrierter




Beitrag arogmyxdfa Unregistrierter 21:57:40 08.08.2012   Titel:              Zitieren

C++:
template <class T>          bool is_mfun (T*    ) { return false; }
template <class C, class T> bool is_mfun (T C::*) { return true;  }
wxSkip
Mitglied

Benutzerprofil
Anmeldungsdatum: 16.11.2009
Beiträge: 1985
Beitrag wxSkip Mitglied 23:16:03 08.08.2012   Titel:              Zitieren

arogmyxdfa schrieb:
C++:
template <class T>          bool is_mfun (T*    ) { return false; }
template <class C, class T> bool is_mfun (T C::*) { return true;  }

Das prüft lediglich, ob du einen Pointer auf einen Member hast, nicht einen Pointer auf eine Memberfunktion. Zudem wird es einen Fehler bei allen Nicht-Pointer-Aufrufen geben...

@Nash26:
Tja, ohne Variadic Templates wird dir wohl nichts anderes übrig bleiben, als is_member_function_ptr für eine ausreichende Anzahl an Parametern zu spezialisieren:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template<typename T> struct is_member_function_ptr
{
    static const bool value = false;
};
 
template<typename Ret, typename Class> struct is_member_function_ptr<Ret (Class::*)()>
{
    static const bool value = true;
};
 
template<typename Ret, typename Class, typename T1> struct is_member_function_ptr<Ret (Class::*)(T1)>
{
    static const bool value = true;
};
 
template<typename Ret, typename Class, typename T1, typename T2> struct is_member_function_ptr<Ret (Class::*)(T1, T2)>
{
    static const bool value = true;
};
 
//...

_________________
Je mehr Käse, desto mehr Löcher. Je mehr Löcher, desto weniger Käse. Also: Je mehr Käse, desto weniger Käse!
camper
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.08.2004
Beiträge: 5794
Beitrag camper Mitglied 00:29:16 09.08.2012   Titel:              Zitieren

wxSkip schrieb:
arogmyxdfa schrieb:
C++:
template <class T>          bool is_mfun (T*    ) { return false; }
template <class C, class T> bool is_mfun (T C::*) { return true;  }

Das prüft lediglich, ob du einen Pointer auf einen Member hast, nicht einen Pointer auf eine Memberfunktion.
Nicht ganz, auch Zeiger-auf-non-const-Memberfunktionen sind erfasst (in diesem Fall wird T als Funktionstyp deduziert).
Nash26
Mitglied

Benutzerprofil
Anmeldungsdatum: 12.10.2009
Beiträge: 32
Beitrag Nash26 Mitglied 08:14:14 09.08.2012   Titel:              Zitieren

Kennt ihr das Buch C++ Templates the complete guide?

Dort schreibt der Autor das es auch ohne die vielen parameter variationen geht:
Hier benutzt er es um zu überprüfen ob eine Funktion gegeben ist oder nicht.
http://www.josuttis.com/tmplbook/functors/typet.hpp.html

@arogmyxdfa
bei anderen typen soll es aber nicht zum compile Fehler kommen
pumuckl
Moderator

Benutzerprofil
Anmeldungsdatum: 21.06.2005
Beiträge: 7326
Beitrag pumuckl Moderator 10:33:25 09.08.2012   Titel:              Zitieren

Nash26 schrieb:
Boost kann ich leider nicht verwenden.

Was hindert dich? Die typetraits von boost sind header-only, keine Installation, kein Linken, kein separates Übersetzen von Biblitoheken nötig.

_________________
Du brauchst Hilfe? - Forenregeln. Den richtigen Code posten - machs uns einfacher dir zu helfen
Don't feed the Help Vampires!
knivil
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.02.2009
Beiträge: 5861
Beitrag knivil Mitglied 10:44:27 09.08.2012   Titel:              Zitieren

Nicht ganz das, was du suchst, aber vielleicht enthaelt es Anregungen: http://stackoverflow.com/ ....... ent-has-a-member-function

Die Frage ist natuerlich, warum du das brauchst!

_________________
If it were not for laughter, there would be no Tao.
Sie können einen Beitrag nicht so schnell nach Ihrem letzten absenden, bitte warten Sie einen Augenblick.


Zuletzt bearbeitet von knivil am 10:45:52 09.08.2012, insgesamt 1-mal bearbeitet
camper
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.08.2004
Beiträge: 5794
Beitrag camper Mitglied 11:30:01 09.08.2012   Titel:              Zitieren

Nash26 schrieb:
Kennt ihr das Buch C++ Templates the complete guide?

Dort schreibt der Autor das es auch ohne die vielen parameter variationen geht:
Hier benutzt er es um zu überprüfen ob eine Funktion gegeben ist oder nicht.
http://www.josuttis.com/tmplbook/functors/typet.hpp.html

@arogmyxdfa
bei anderen typen soll es aber nicht zum compile Fehler kommen
Dann hast du doch schon eine Lösung.
In C++03 gibt es keine schöne Lösung dafür, da es keine Möglichkeit gibt, den Typ von Memberfunktionszeiger generisch aufzuschreiben (mangels variadic templates).
Es bleiben zwei Alternativen:
1. viele Spezialisierungen für ausreichend viele Parameter, Nachteil: eine Menge Codeduplikation, folglich langsames Compilieren, nicht allgemeingültig, falls doch mal längere Parameterlisten benötigt werden
2. durch Eliminierung, wenn alle anderen Typen ausgeschlossen werden, muss ein Memberfunktionszeiger übrig bleiben, Nachteil: funktioniert ggf. nicht mehr, wenn weitere Typen dazukommen, die usprünglich nicht existierten (Compilererweiterungen, neue Standards...).

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

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <bool b> struct bool_ { static const bool value = b; };
typedef bool_<false> false_type;
typedef bool_<true> true_type;
 
template <typename T, typename U> struct is_same : false_type {};
template <typename T> struct is_same<T, T> : true_type {};
 
template <typename T> struct is_function : is_same<void(T),void(T*)> {};
// Spezialisierungen für Typen, für die void(T) oder void(T*) ill-formed ist:
// leidet unter dem gleichen Problem wie 2., weil auch für rvalue-Referenzen spezialisiert werden müsste; kann man durch den sizeof-SFINAE-Trick in den Griff kriegen, ist mir aber hier zuviel Schreibarbeit
template <> struct is_function<const void> : false_type {};            //
template <> struct is_function<volatile void> : false_type {};         // kann nicht als Funktionsparameter auftreten (da immer unvollständig), die Sonderregel gilt nur für unqualifiziertes void
template <> struct is_function<const volatile void> : false_type {};   //
template <typename T> struct is_function<T&> : false_type {}; // kann keine Zeiger auf Referenzen bilden
 
template <typename T> struct is_mem_fun_ptr : false_type {};
template <typename T, typename C> struct is_mem_fun_ptr<T C::*> : is_function<T> {};


Zuletzt bearbeitet von camper am 12:22:36 09.08.2012, insgesamt 6-mal bearbeitet
Nash26
Mitglied

Benutzerprofil
Anmeldungsdatum: 12.10.2009
Beiträge: 32
Beitrag Nash26 Mitglied 20:17:07 09.08.2012   Titel:              Zitieren

ist ja interesant, dein code funktioniert. Prima.


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

Aber warum wird diese spezialisierung instanziert, obwohl ich ein ein type mit 10 parametern übergebe?


Soweit ich das jetzt verstehe, brichst du das ganze schnell runter zu einem
test für is_function_ptr.

Das hier verstehe ich leider nicht:
Code:
template <typename T> struct is_function : is_same<void(T),void(T*)> {};
camper
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.08.2004
Beiträge: 5794
Beitrag camper Mitglied 20:50:45 09.08.2012   Titel:              Zitieren

Nash26 schrieb:
ist ja interesant, dein code funktioniert. Prima.


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

Aber warum wird diese spezialisierung instanziert, obwohl ich ein ein type mit 10 parametern übergebe?
Weil T selbst ein Funktionstyp sein kann. Und das passiert genau dann, wenn du das Template mit einem Zeiger auf non-const-non-volatile-Memberfunktion fütterst.
Nimmst du in
C++:
T (C::*)(...)
den Deklarator ::* weg, bleibt ein Funktionstyp stehen. Leider können auf diese weise const und volatile Memberfunktionen nicht verarbeitet werden, weil Funktionstypen nicht qualifiziert sein dürfen (eine Einschränkung, für die mehr der Grund nie ganz klar geworden ist; dass Funktionen selbst nie qualifiziert sind, muss ja nichts mit dem Typen zu tun haben). Das führt zu der kuriosen Eigenschaft dass in z.B.
C++:
T (C::*)(...)const
nach Wegnahme des Deklarator ::* etwas steht, was kein (legaler) Typ ist. Da Deklaratoren aber eigentlich einen Typ aus einem anderen ableiten, ist das in meinem Augen seltsam.

Nash26 schrieb:
Das hier verstehe ich leider nicht:
Code:
template <typename T> struct is_function : is_same<void(T),void(T*)> {};
Der Test basiert auf den Besonderheiten die für die Deklarationen von Funktionsparametern gelten. Wird ein Funktionsparameter als Funktionstyp deklariert, so transformiert der Compiler das in eine Deklaration eines Funktionszeigers als Parameter (analog für Arrays, allerdings ist das Ergebnis der Transformation dort nicht ein Zeiger auf das Array sondern einer auf den Elementtyp). Es spielt also bei Funktionenparametern keine Rolle, ob ausdrücklich ein Zeiger deklariert wird, die Deklaration verweist trotzdem auf den selben Typ. Und das gilt so nur für Funktionstypen.

Dein verlinkter Code nutzt übrigens die gleiche Eigenschaft, nur wird hier der sizeof-Überladungstrick angewendet.


Zuletzt bearbeitet von camper am 20:52:06 09.08.2012, insgesamt 1-mal bearbeitet
c++.de :: C++ (auch C++0x und C++11) ::  Check für is member function pointer  
Gehen Sie zu Seite 1, 2, 3, 4  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.