[C++] this und const
- RustySpoon
- Establishment
- Beiträge: 298
- Registriert: 17.03.2009, 13:59
- Wohnort: Dresden
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [C++] this und const
Offiziell ist this als (pure) R-Value spezifiziert, also die Adresse deines Objektes in Form eines temporären Wertes vom Typ T* in unqualifizierten oder const T* in const-qualifizierten Methoden.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- RustySpoon
- Establishment
- Beiträge: 298
- Registriert: 17.03.2009, 13:59
- Wohnort: Dresden
Re: [C++] this und const
Danke für die Antwort, erscheint mir soweit erstmal plausibel.
Du sagst "offiziell", ist es möglich, dass unterschiedliche Compiler das unterschiedlich handhaben? Bzw. ist das eventuell irgendwie eklig vom Kontext abhängig?
Worum es mir konkret geht ist Folgendes:
Das ist letztendlich einfach eine Realisierung des CRTP-Idioms. State ist die abgeleitete Klasse. Leider bekomm ich beim Kompilieren (GCC 4.7.1) immer folgenden Fehler (aus Gründen der Lesbarkeit etwas gekürzt):
std::is_const sollte meines Erachtens zu true evaluieren - tut es aber nicht.
Bastel ich dazu ein Minimalbeispiel funktioniert es. Scheinbar hab ich also nur Tomaten auf den Augen.
Any ideas?
Du sagst "offiziell", ist es möglich, dass unterschiedliche Compiler das unterschiedlich handhaben? Bzw. ist das eventuell irgendwie eklig vom Kontext abhängig?
Worum es mir konkret geht ist Folgendes:
Code: Alles auswählen
inline variable_type watcher2(clause_type clause) const
{
return static_cast<
typename std::conditional<
std::is_const<typename std::remove_pointer<decltype(this)>::type>::value,
State const* const,
State* const>::type>(this)->inner_state()[clause].watcher2;
}
watcher_facet ist die CRTP-Basisklasse, walksat_state die Abgeleitete.error: static_cast from type 'const watcher_facet<walksat_state, ...>* const' to type 'std::conditional<false, const walksat_state* const, walksat_state* const>::type {aka walksat_state* const}' casts away qualifiers
std::is_const sollte meines Erachtens zu true evaluieren - tut es aber nicht.
Bastel ich dazu ein Minimalbeispiel funktioniert es. Scheinbar hab ich also nur Tomaten auf den Augen.
Any ideas?
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [C++] this und const
Läuft das Minimalbeispiel denn auch in deinem Compiler? Welchen Typ gibt decltype(this) bzw. typename std::remove_pointer<decltype(this)>::type bei dir denn im Kontext zurück?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- RustySpoon
- Establishment
- Beiträge: 298
- Registriert: 17.03.2009, 13:59
- Wohnort: Dresden
Re: [C++] this und const
Japp, läuft bei mir auch tadellos.
Langsam bekomm ich Licht ins Dunkel und meine Verwirrungen.
Hier hab ich mal die einzelnen Typen aufgeschlüsselt. Erstmal ist festzuhalten: Du hast Recht, der this-Typ ist T const* innerhalb einer const-Methode.
Strange ist nun allerdings die oben genannte Fehlermeldung. Der Compiler scheint im Fall des Casts ja von const watcher_facet<walksat_state, ...>* const auszugehen. Rührt das daher, dass this R-Value ist?
Das eigentliche Problem kommt aber woanders her. Das Anwenden von std::remove_pointer bzw. Dereferenzieren von this führt dazu, dass sich der Typ von T const* (const) hin zu T verändert. Ich hatte da irgendwie nicht länger drüber nachgedacht und intuitiv T const angenommen. Diesbezüglich bitte ich auch noch um Aufklärung, so richtig ist der Groschen nämlich noch nicht gefallen.
Ist das Problem irgendwie angekommen? Vielen Dank für die Hilfe!
Edit: Gut, hab die letzte Frage mal rausredigiert, das war banal.
Langsam bekomm ich Licht ins Dunkel und meine Verwirrungen.
Hier hab ich mal die einzelnen Typen aufgeschlüsselt. Erstmal ist festzuhalten: Du hast Recht, der this-Typ ist T const* innerhalb einer const-Methode.
Strange ist nun allerdings die oben genannte Fehlermeldung. Der Compiler scheint im Fall des Casts ja von const watcher_facet<walksat_state, ...>* const auszugehen. Rührt das daher, dass this R-Value ist?
Das eigentliche Problem kommt aber woanders her. Das Anwenden von std::remove_pointer bzw. Dereferenzieren von this führt dazu, dass sich der Typ von T const* (const) hin zu T verändert. Ich hatte da irgendwie nicht länger drüber nachgedacht und intuitiv T const angenommen. Diesbezüglich bitte ich auch noch um Aufklärung, so richtig ist der Groschen nämlich noch nicht gefallen.
Ist das Problem irgendwie angekommen? Vielen Dank für die Hilfe!
Edit: Gut, hab die letzte Frage mal rausredigiert, das war banal.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [C++] this und const
Achtung, typeid entfernt top-level Qualifizier und Referenzen. Nur weil da kein const ausgegeben wird, ist es noch lange nicht weg. Bis hin zu einem unqualifizierten T ändert sich da nämlich nichts. Für vernünftige Typausgabe kommst wohl um ein winziges Hilfstemplate nicht drumrum (auch gerade beim Beantworten deines Posts zum ersten Mal gebaut, warum hat die STL sowas nicht?!):RustySpoon hat geschrieben:Hier hab ich mal die einzelnen Typen aufgeschlüsselt. Erstmal ist festzuhalten: Du hast Recht, der this-Typ ist T const* innerhalb einer const-Methode.
[...]
Das Anwenden von std::remove_pointer bzw. Dereferenzieren von this führt dazu, dass sich der Typ von T const* (const) hin zu T verändert. Ich hatte da irgendwie nicht länger drüber nachgedacht und intuitiv T const angenommen. Diesbezüglich bitte ich auch noch um Aufklärung, so richtig ist der Groschen nämlich noch nicht gefallen.
Code: Alles auswählen
template <class T> struct type_printer { static void print() { std::cout << typeid(T).name(); } };
template <class T> struct type_printer<T const> { static void print() { type_printer<T>::print(); std::cout << " const"; } };
template <class T> struct type_printer<T*> { static void print() { type_printer<T>::print(); std::cout << " *"; } };
template <class T> struct type_printer<T&> { static void print() { type_printer<T>::print(); std::cout << " &"; } };
Code: Alles auswählen
decltype(this):
4baseI7derivedE const *
typename std::remove_pointer<decltype(this)>::type:
4baseI7derivedE const
decltype(*this):
4baseI7derivedE const &
typename std::conditional< std::is_const< typename std::remove_pointer<decltype(this)>::type>::value, Derived const* const, Derived* const>::type:
7derived const * const
const method
Exakt, C++ nimmt es mit R-Values immer noch einigermaßen genau und erlaubt sinnigerweise keine Zuweisung zu temporären Objekten.RustySpoon hat geschrieben:Strange ist nun allerdings die oben genannte Fehlermeldung. Der Compiler scheint im Fall des Casts ja von const watcher_facet<walksat_state, ...>* const auszugehen. Rührt das daher, dass this R-Value ist?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- RustySpoon
- Establishment
- Beiträge: 298
- Registriert: 17.03.2009, 13:59
- Wohnort: Dresden
Re: [C++] this und const
Naja, nachdem du meine Gedanken jetzt entquirlt hast, hab ich mir einfach ein kleines std::is_const-like Hilfstemplate gebastelt, welches testet, ob der Basistyp eines Zeigers const-qualifiziert ist. Damit funktioniert erstmal alles super. Danke für die ausführlichen Erklärungen, hab so einiges dabei gelernt!CodingCat hat geschrieben:Viel wichtiger wäre jetzt, dass du derlei Analyse mal in deinem Kontext durchführst (siehe Hilfsmakros im verlinkten Paste, um den Überblick über die Typzuordnung nicht zu verlieren).
Btw.: Flattr-Buttons und 'ne Ideone-Integration im Forum wären irgendwie schön. Würde dem Kater/den Betreibern jetzt gern was Gutes tun... ;)