const_cast в шаблоне. Есть ли модификатор absst? - PullRequest
5 голосов
/ 04 октября 2009

У меня есть шаблон класса, подобный этому:

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

Иногда я хочу использовать класс с константным типом T следующим образом:

MyClass<const MyObject> mci;

но я хочу изменить данные, используя const_cast<MyObject*>data (не важно, почему, но MyClass - это класс интеллектуальных указателей подсчета ссылок, который хранит счетчик ссылок в самих данных. MyObject происходит от некоторого типа содержит количество Данные не должны быть изменены, но счет должен быть изменен умным указателем.).

Есть ли способ удалить константу из T? Вымышленный код:

const_cast<unconst T>(data) 

Ответы [ 5 ]

12 голосов
/ 04 октября 2009

Самый простой способ - сделать счетчик ссылок изменяемым.

Однако, если вы заинтересованы в том, как это будет работать с const_cast, то переопределение усиления remove_const должно быть довольно простым:

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();
5 голосов
/ 04 октября 2009

У вас есть ответ. const_cast работает в обоих направлениях:

char* a;
const char* b;

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

Что касается конкретной проблемы, рассматривали ли вы изменяемое ключевое слово? Это позволяет изменять переменную-член внутри метода const.

class foo {
    mutable int x;
public:
    inc_when_const() const { ++x; }
    dec_when_const() const { --x; }
};
4 голосов
/ 04 октября 2009

Сделайте счетчик ссылок изменяемым в классе, управляемом вашим навязчивым указателем. Это вполне разумно и точно отражает «логическую константность» - то есть изменение счетчика ссылок на объект не отражает каких-либо изменений в состоянии самого объекта. Другими словами, счетчик ссылок не является логически частью объекта - объект просто оказывается удобным местом для хранения этих полуотносимых данных.

3 голосов
/ 04 октября 2009

Если вы можете использовать Boost, библиотека Type Traits предоставляет метафункцию remove_const , которая делает это.

0 голосов
/ 31 мая 2014

Вот моя функция C ++ 11 unconst template.

Если вы используете его, вы заигрываете с неопределенное поведение . Вы были предупреждены .

// 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;
}
...