【问题标题】:How to avoid mutable in this case在这种情况下如何避免可变
【发布时间】:2016-07-05 12:41:48
【问题描述】:

考虑一下:

struct Foo {
    std::vector<double> x;
    mutable double* xp;
    void foo () const { xp = &(x[0]); }    
};

这不会编译,因为 error: invalid conversion from 'const double*' to 'double*' [-fpermissive]

修复相当简单:

struct Foo {
    mutable std::vector<double> x;
    mutable double* xp;
    void foo () const { xp = &(x[0]); }    
};

但是如果我不想让向量可变怎么办?在这种情况下,从 const 向量获取指向非 const 的指针的最佳方法是什么?

我要解决的问题如下:

我有一些看起来像这样的代码(抱歉不能发布完整的代码):

struct Foo {
    mutable DataSource data;                                   
    void load(int index) const {  data->GetEntry(index); }   
    void getX()          const { return data->element->x; }        
};

我无法更改DataSource 的位置,它的GetEntry 从文件中读取以更新其element。以这种方式读取文件比较慢,因此我想将其更改为

struct Foo {
   mutable DataSource data;
   std::vector<DataSource::Element> elements;
   DataSource::Element* current;
   void loadAll() {  /*... read all elements into the vector ...*/ }
   void load(int index) const { current = &(elements[index]); }   
   void getX()          const { return current->x; }        
};      

因为我可以在不破坏(大量)现有代码的情况下做到这一点。我可以完全放弃 constness,这可能是一个更好的设计,但如果可能的话,我想避免这种情况,因为那样我必须在其他地方解决问题。

【问题讨论】:

  • 为什么你想要一个指向非const的指针?真正的问题是什么?
  • 没有“最好的方法”。这个looks like an XY problem。您要解决的真正问题是什么。不,不是这里要问的问题,而是您认为其解决方案涉及可变类成员的问题,而您要问的是。
  • 请记住,如果您从不修改 *xp 或对 *xp 进行非 const 引用,您也可以拥有一个指向 const 对象的可变指针,即 mutable const double *xp; void foo() const { xp = &amp;x[0]; } 是完全有效的。
  • 为什么load()首先被声明为const函数,而它的唯一目的显然是改变对象的状态?
  • 可能@majk 的评论是您正在寻找的解决方案。我会注意到void getX() const { return current-&gt;x; } 不会编译。所以这些都不是真正的代码,当你发布一个只对问题进行模糊描述的问题时,获得最佳答案的机会很渺茫。

标签: c++ vector constants mutable


【解决方案1】:

我们用于不久前没有实现mutable 的编译器的一个老技巧是const_cast 去掉this 对象的常量,例如:

void foo () const { xp = &( (const_cast<Foo*>(this)->x)[0]); }    

也非常适合您的情况。

【讨论】:

  • (不是反对者)我同意这个“有效”,因为它使编译器停止抱怨,但需要提到 OP 正在进入未定义的行为领域。他们试图这样做的事实表明需要解决一个设计缺陷。
  • 从 OP 所写的内容来看,他们的界面在 const 正确性方面似乎存在一些严重的设计缺陷。这实际上只会使代码编译,但并不能解决该代码的任何实际问题。
  • @fritzone:这是你试图完成的事情吗?听上去,你是故意误导OP?
  • @AndyG 一点也不,这也让我感到惊讶。而且我绝对不想用答案误导任何人,我只记得我们前段时间在非完全符合标准的编译器时代使用的旧技术,我们曾经用来“破解”这样的情况。确实,这种情况的 const 正确性有一些需要,但如果没有对整个情况有更深入的了解,这是我编译代码最接近的方法。
  • 如果我可以评论...问题是询问如何使其编译(如果需要快速和肮脏)。我知道这个设计有一个严重的缺陷,但在目前的阶段,我必须忍受它并让它以某种方式运行。因此,这个答案对我来说是可以接受的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-14
  • 1970-01-01
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多