Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>As AndreyT pointed out, under these circumstances assignment (mostly) doesn't make a lot of sense. The problem is that <code>vector</code> (for one example) is kind of an exception to that rule.</p> <p>Logically, you copy an object into the <code>vector</code>, and sometime later you get back another copy of the original object. From a purely logical viewpoint, there's no assignment involved. The problem is that <code>vector</code> requires that the object be assignable anyway (actually, all C++ containers do). It's basically making an implementation detail (that somewhere in its code, it might assign the objects instead of copying them) part of the interface.</p> <p>There is no simple cure for this. Even defining your own assignment operator and using <code>const_cast</code> doesn't really fix the problem. It's perfectly safe to use <code>const_cast</code> when you get a <code>const</code> pointer or reference to an object that you know isn't actually defined to be <code>const</code>. In this case, however, the variable itself <em>is</em> defined to be <code>const</code> -- attempting to cast away the <code>const</code>ness and assign to it gives undefined behavior. In reality, it'll almost always work anyway (as long as it's not <code>static const</code> with an initializer that's known at compile time), but there's no guarantee of it.</p> <p>C++ 11 and newer add a few new twists to this situation. In particular, objects no longer <em>need</em> to be assignable to be stored in a vector (or other collections). It's sufficient that they be movable. That doesn't help in this particular case (it's no easier to move a <code>const</code> object than it is to assign it) but does make life substantially easier in some other cases (i.e., there are certainly types that are movable but not assignable/copyable).</p> <p>In this case, you <em>could</em> use a move rather than a copy by adding a level of indirection. If your create an "outer" and an "inner" object, with the <code>const</code> member in the inner object, and the outer object just containing a pointer to the inner:</p> <pre><code>struct outer { struct inner { const double coeff; }; inner *i; }; </code></pre> <p>...then when we create an instance of <code>outer</code>, we define an <code>inner</code> object to hold the <code>const</code> data. When we need to do an assignment, we do a typical move assignment: copy the pointer from the old object to the new one, and (probably) set the pointer in the old object to a nullptr, so when it's destroyed, it won't try to destroy the inner object.</p> <p>If you wanted to badly enough, you could use (sort of) the same technique in older versions of C++. You'd still use the outer/inner classes, but each assignment would allocate a whole new inner object, or you'd use something like a shared_ptr to let the outer instances share access to a single inner object, and clean it up when the last outer object is destroyed.</p> <p>It doesn't make any real difference, but at least for the assignment used in managing a vector, you'd only have two references to an <code>inner</code> while the <code>vector</code> was resizing itself (resizing is why a vector requires assignable to start with).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload