我有一个这样的模板类:
template<T>
class MyClass
{
T* data;
}
有时,我想使用具有常量类型T的类,如下所示:
MyClass<const MyObject> mci;
但是我想使用const_cast<MyObject*>data
修改数据(但为什么MyClass
是引用计数智能指针类并不重要,它会将引用计数保留在数据本身中。MyObject
派生自某种包含计数的类型。
不应修改数据,但必须通过智能指针修改计数。)。
有没有办法从T
删除常量?虚构代码:
const_cast<unconst T>(data)
答案 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;
}