Question

J'ai une classe de modèle comme celui-ci:

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

Parfois, je veux utiliser la classe avec un type T constante comme suit:

MyClass<const MyObject> mci;

mais je veux modifier les données à l'aide const_cast<MyObject*>data (il est important de pourquoi, mais MyClass est une classe de pointeur intelligent de comptage de référence qui maintient le compte de référence dans les données elles-mêmes. MyObject est dérivé d'un certain type qui contient le compte. Les données ne doit pas être modifiée, mais le nombre doit être modifié par le pointeur intelligent.).

Y at-il un moyen de supprimer const-ness de T? Code fictionnelle:

const_cast<unconst T>(data) 

Était-ce utile?

La solution

La façon la plus simple serait ici de faire le compte de référence mutable.

Toutefois, si vous êtes intéressé par la façon dont il travaillerait avec le const_cast, réimplémentant alors le remove_const de boost devrait être assez simple:

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

Autres conseils

Vous avez la réponse. const_cast fonctionne dans les deux sens:

char* a;
const char* b;

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

Quant à vous question spécifique, avez-vous considéré le mot-clé mutable? Il permet une variable membre à modifier dans une méthode const.

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

Faire le compte de référence mutable dans la classe gérée par votre pointeur intrusif. Ceci est tout à fait raisonnable, et reflète « constness logique » correctement exactement - à savoir changer le compteur de référence de l'objet ne reflète aucun changement dans l'état de l'objet lui-même. En d'autres termes, le nombre de références est pas logiquement partie de l'objet - l'objet se trouve être un endroit pratique pour stocker ces données semi-indépendant

.

Si vous pouvez utiliser Boost, la bibliothèque de type fournit la caractères remove_const métafonction qui fait cela.

Voici mon C ++ 11 fonction unconst template.

Si vous l'utilisez, vous flirtent avec le titre comportement non défini . Vous avez été averti .

// 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;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top