const_cast in template. Is there a unconst modifier?

不羁岁月 提交于 2019-12-22 06:59:25

问题


I have a template class like this:

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

Sometimes, I want to use the class with a constant type T as follows:

MyClass<const MyObject> mci;

but I want to modify the data using const_cast<MyObject*>data (it is not important why but MyClass is a reference count smart pointer class which keeps the reference count in the data itself. MyObject is derived from some type which contains the count. The data should not be modified but the count must be modified by the smart pointer.).

Is there a way to remove const-ness from T? Fictional code:

const_cast<unconst T>(data) 

?


回答1:


The simplest way here would be to make the reference count mutable.

However, if you are interested in how it would work with the const_cast, then reimplementing boost's remove_const should be quite 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();



回答2:


You have the answer. const_cast works in both directions:

char* a;
const char* b;

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

As for you specific issue, have you considered the mutable keyword? It allows a member variable to be modified inside a const method.

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



回答3:


Make the reference count mutable in the class managed by your intrusive pointer. This is entirely reasonable, and reflects "logical constness" exactly correctly -- i.e. changing the object's reference count does not reflect any change in the state of the object itself. In other words, the reference count isn't logically part of the object -- the object just happens to be a convenient place to store this semi-unrelated data.




回答4:


If you can use Boost, the Type Traits library provides the remove_const metafunction that does that.




回答5:


Here is my C++11 unconst function template.

If you use it, you are flirting with undefined behavior. You have been warned.

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


来源:https://stackoverflow.com/questions/1516563/const-cast-in-template-is-there-a-unconst-modifier

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!