[C++] this und const
Verfasst: 06.03.2013, 14:32
Die deutsche Spieleentwickler-Community (seit 1999).
https://zfx.info/
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
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?
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).