const_cast в шаблоне.Существует ли модификатор unconst?

StackOverflow https://stackoverflow.com/questions/1516563

Вопрос

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

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

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

MyClass<const MyObject> mci;

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

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

const_cast<unconst T>(data) 

?

Это было полезно?

Решение

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

Однако, если вас интересует, как это будет работать с const_cast, затем переопределение boost's 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();

Другие советы

У вас есть ответ.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

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

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

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

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

Вот мой 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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top