Frage

Ich habe eine Vorlagenklasse wie diese:

template<T>
class MyClass
{
  T* data;
}

Manchmal möchte ich die Klasse mit einem konstanten Typ t wie folgt verwenden:

MyClass<const MyObject> mci;

Aber ich möchte die Daten verwenden const_cast<MyObject*>data (Es ist nicht wichtig, warum MyClass ist eine Referenzzahl intelligente Zeigerklasse, die die Referenzzahl in den Daten selbst hält. MyObject wird von einem Typ abgeleitet, der die Anzahl enthält. Die Daten sollten nicht geändert werden, aber die Anzahl muss vom intelligenten Zeiger geändert werden.).

Gibt es eine Möglichkeit, Const-Ness aus zu entfernen? T? Fiktioneller Code:

const_cast<unconst T>(data) 

?

War es hilfreich?

Lösung

Der einfachste Weg hierher wäre es, die Referenz zu veränderlich zu zählen.

Wenn Sie jedoch daran interessiert sind, wie es mit dem funktionieren würde const_cast, dann neu auf Boosts neu auf remove_const sollte ganz einfach sein:

template <class T>
struct RemoveConst
{
    typedef T type;
};

template <class T>
struct RemoveConst<const T>
{
    typedef T type;
};

const_cast<typename RemoveConst<T>::type*>(t)->inc();

Andere Tipps

Sie haben die Antwort. const_cast funktioniert in beide Richtungen:

char* a;
const char* b;

a = const_cast<char*>(b);
b = const_cast<const char*>(a); // not strictly necessarily, just here for illustration

Haben Sie das veränderliche Keyword in Betracht gezogen? Es ermöglicht eine Mitgliedsvariable, innerhalb einer CONT -Methode zu modifizieren.

class foo {
    mutable int x;
public:
    inc_when_const() const { ++x; }
    dec_when_const() const { --x; }
};

Machen Sie die Referenzzahl in der Klasse, die von Ihrem intrusiven Zeiger verwaltet wird. Dies ist völlig vernünftig und spiegelt "logische Konstanz" genau richtig wider. Das Ändern der Referenzzahl des Objekts spiegelt keine Änderung im Status des Objekts selbst wider. Mit anderen Worten, die Referenzzahl ist nicht logisch Teil des Objekts-das Objekt ist zufällig ein bequemer Ort, um diese halbbezogenen Daten zu speichern.

Wenn Sie Boost verwenden können, bietet die Typ -Merkmalsbibliothek die entfernen_const Metafunktion das.

Hier ist mein C ++ 11 unconst Funktion template.

Wenn Sie es verwenden, flirten Sie mit undefiniertes Verhalten. Du bist gewesen gewarnt.

// on Ubuntu (and probably others) compile and test with                                                        
//   g++ -std=c++11 test.c  &&  ./a.out  ;  echo $?                             

template < class T >  T &  unconst  ( T const & t ) {
  return  const_cast < T & >  ( t ) ; 
}

// demonstration of use

struct {
  const int n = 4;
} s;

int main () {
  unconst ( s.n ) = 5;
  return s.n;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top