模板中的const_cast。有没有一个不对称的修饰符?

时间:2009-10-04 14:39:15

标签: c++ templates const const-cast

我有一个这样的模板类:

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

有时,我想使用具有常量类型T的类,如下所示:

MyClass<const MyObject> mci;

但是我想使用const_cast<MyObject*>data修改数据(但为什么MyClass是引用计数智能指针类并不重要,它会将引用计数保留在数据本身中。MyObject派生自某种包含计数的类型。 不应修改数据,但必须通过智能指针修改计数。)。

有没有办法从T删除常量?虚构代码:

const_cast<unconst T>(data) 

5 个答案:

答案 0 :(得分:12)

这里最简单的方法是使引用计数可变。

但是,如果您对如何使用const_cast感兴趣,那么重新实现boost 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();

答案 1 :(得分:5)

你有答案。 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; }
};

答案 2 :(得分:4)

在由侵入式指针管理的类中使引用计数可变。这是完全合理的,并且完全正确地反映了“逻辑常数” - 即更改对象的引用计数并不反映对象本身状态的任何变化。换句话说,引用计数在逻辑上不是对象的一部分 - 对象恰好是存储这种半无关数据的便利位置。

答案 3 :(得分:3)

如果你可以使用Boost,Type Traits库提供了remove_const元函数。

答案 4 :(得分:0)

这是我的C ++ 11 unconst函数template

如果你使用它,你就是在用 undefined behavior 调情。您已被警告

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