模板中的 const_cast。有 unconst 修饰符吗?

发布于 2024-08-06 20:23:09 字数 496 浏览 8 评论 0原文

我有一个像这样的模板类:

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

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

MyClass<const MyObject> mci;

但我想使用 const_castdata 修改数据(它不是重要的是,MyClass 是一个引用计数智能指针类,它将引用计数保留在数据本身中,MyObject 是从包含计数的某种类型派生的。 数据不应被修改,但计数必须由智能指针修改。)。

有没有办法从 T 中删除 const-ness?虚构代码:

const_cast<unconst T>(data) 

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) 

?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

So尛奶瓶 2024-08-13 20:23:09

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

但是,如果您对它如何与 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();

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();
热风软妹 2024-08-13 20:23:09

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

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; }
};
烧了回忆取暖 2024-08-13 20:23:09

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

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.

两个我 2024-08-13 20:23:09

如果您可以使用 Boost,则类型特征库提供 remove_const 元函数可以做到这一点。

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

嘿嘿嘿 2024-08-13 20:23:09

这是我的 C++11 unconst 函数模板

如果你使用它,你就是在调情 未定义的行为。您已被警告

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

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文