2009-10-04 11 views
5

Mam klasy szablon tak:const_cast w szablonie. Czy istnieje modyfikator niezgodności?

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

Czasami chcę użyć klasy ze stałą typu T, co następuje:

MyClass<const MyObject> mci; 

ale chcę, aby zmodyfikować dane używając const_cast<MyObject*>data (nie jest ważne dlaczego ale MyClass jest klasą inteligentnych wskaźników licznika odwołań, która przechowuje licznik odwołań w samych danych.MyObject pochodzi z pewnego typu, który zawiera licznik. Dane nie powinny być modyfikowane, ale liczba musi być modyfikowana przez inteligentny wskaźnik.).

Czy istnieje sposób usunięcia konstelacji z T? Fikcyjny kod:

const_cast<unconst T>(data) 

?

Odpowiedz

11

Najprostszym sposobem byłoby sprawienie, aby licznik odwołań był zmienny.

Jednakże, jeśli jesteś zainteresowany w jaki sposób pracować z const_cast, następnie reimplementing doładowania na remove_const powinna być dość prosta:

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

Dziękuję za wyjaśnienie, jak działa remove_const. – danatel

+3

@danatel: Naprawdę nie chcesz używać remove_const.Modyfikowanie wartości const przez odrzucanie constness jest niezdefiniowanym zachowaniem. Chcesz użyć __mutable__ na zmiennej refcount. –

+0

:-) Używam mutable. Nie potrzebowałem rozwiązania mojego problemu, problem był tam jako ilustracja (proszę przeczytać oryginalny post) - Byłem ciekawy, czy istnieje sposób na usunięcie stałości. – danatel

5

Masz odpowiedź. const_cast działa w obie strony:

char* a; 
const char* b; 

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

Co do konkretnego problemu, czy uznano (a) Pan/Pani za zmienne słowo kluczowe? Pozwala na modyfikację zmiennej składowej wewnątrz metody const.

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

Ale to jest klasa szablonów. T jest czymś stałym. Pytanie brzmi: w jaki sposób utworzyć coś nonconst z T? – danatel

+1

+1 Mutable to odpowiedź tutaj. – UncleBens

3

Jeśli można użyć Boost biblioteki typów Cechy zapewnia remove_const metafunkcji że robi.

+0

Niestety, na tym projekcie nie mogę użyć Boost. Ale gdyby istniał łatwy sposób na to w standardowym C++, nikt nie napisałby remove_const. Dlatego nie ma takiego sposobu. – danatel

+0

Czy przeczytałeś inne odpowiedzi? Boost jest po prostu metatechową wersją, po prostu użyj const_cast i usuń z niej const lub mutable, jak powiedział jumcchellio. – GManNickG

4

Dokonaj zmiany liczby odwołań w klasie zarządzanej przez twój natrętny wskaźnik. Jest to całkowicie uzasadnione i dokładnie odzwierciedla "stałą logiczną" - tj. Zmiana liczby odniesienia obiektu nie odzwierciedla żadnych zmian stanu samego obiektu. Innymi słowy, licznik referencji nie jest logicznie częścią obiektu - obiekt jest dogodnym miejscem do przechowywania tych częściowo niepowiązanych danych.

0

Oto mój C++ 11 unconst funkcja template.

Jeśli używasz go, flirtujesz z undefined behavior. Zostałeś ostrzeżony ostrzeżony.

// 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; 
} 
+0

Myślę, że byłoby to prostsze i ma taki sam efekt: 'template T & unconst (T const & t) {return const_cast (t);}'. – alfC

+0

Dzięki! Jest to prostsze i wydaje się działać. Zastanawiałem się, jaka jest różnica między typename a klasą. – mpb

Powiązane problemy