Domanda

Ho una classe template in questo modo:

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

A volte, voglio usare la classe con un tipo costante T come segue:

MyClass<const MyObject> mci;

ma voglio modificare i dati utilizzando const_cast<MyObject*>data (non è importante perchè ma MyClass è un conteggio di riferimento intelligente classe puntatore che mantiene il conteggio dei riferimenti nei dati stessi. MyObject è derivato da un certo tipo che contiene il conteggio. I dati non deve essere modificato, ma il conteggio deve essere modificata dal puntatore intelligente.).

C'è un modo per rimuovere const-ness da T? Codice immaginario:

const_cast<unconst T>(data) 

È stato utile?

Soluzione

Il modo più semplice sarebbe di fare il conteggio dei riferimenti mutevole.

Tuttavia, se siete interessati a come avrebbe funzionato con la const_cast, poi reimplementare remove_const di spinta dovrebbe essere abbastanza semplice:

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();

Altri suggerimenti

Hai la risposta. const_cast funziona in entrambe le direzioni:

char* a;
const char* b;

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

In quanto a te problema specifico, avete considerato la parola chiave mutevole? Permette una variabile membro da modificare all'interno di un metodo const.

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

Fare il conteggio dei riferimenti mutabile nella classe gestita dal vostro puntatore invadente. Ciò è del tutto ragionevole, e riflette "constness logico" esattamente correttamente - cioè cambiando conteggio di riferimento dell'oggetto non riflette alcun cambiamento nello stato dell'oggetto stesso. In altre parole, il conteggio di riferimento non è logicamente parte dell'oggetto - oggetto sembra appena essere una possibilità di memorizzare questi dati semi-correlato

.

Se è possibile utilizzare Boost, la libreria dei tipi Tratti fornisce il metafunction remove_const che lo fa.

Ecco il mio C ++ 11 funzione unconst template.

Se si utilizza, si stanno flirtando con comportamento indefinito . Lei è stato avvertito .

// 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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top