Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Sounds like you want an object that can wrap either <code>int*</code> (and then behave as non-const), or <code>int const*</code> (and then behave as const). You can't really do it properly with a single class.</p> <p>In fact, the very notion that <code>const</code> applied to your class should change its semantics like that is wrong - if your class models a pointer or an iterator (if it wraps a pointer, it's likely to be the case), then <code>const</code> applied to it should only mean that it cannot be changed itself, and should not imply anything regarding the value pointed to. You should consider following what STL does for its containers - it's precisely why it has distinct <code>iterator</code> and <code>const_iterator</code> classes, with both being distinct, but the former being implicitly convertible to the latter. As well, in STL, <code>const iterator</code> isn't the same as <code>const_iterator</code>! So just do the same.</p> <p><strong>[EDIT]</strong> Here's a tricky way to maximally reuse code between <code>C</code> and <code>const_C</code> while ensuring const-correctness throughout, and not delving into U.B. (with <code>const_cast</code>):</p> <pre><code>template&lt;class T, bool IsConst&gt; struct pointer_to_maybe_const; template&lt;class T&gt; struct pointer_to_maybe_const&lt;T, true&gt; { typedef const T* type; }; template&lt;class T&gt; struct pointer_to_maybe_const&lt;T, false&gt; { typedef T* type; }; template&lt;bool IsConst&gt; struct C_fields { typename pointer_to_maybe_const&lt;int, IsConst&gt;::type i; // repeat for all fields }; template&lt;class Derived&gt; class const_C_base { public: int method() const { // non-mutating method example return *self().i; } private: const Derived&amp; self() const { return *static_cast&lt;const Derived*&gt;(this); } }; template&lt;class Derived&gt; class C_base : public const_C_base&lt;Derived&gt; { public: int method() { // mutating method example return ++*self().i; } private: Derived&amp; self() { return *static_cast&lt;Derived*&gt;(this); } }; class const_C : public const_C_base&lt;const_C&gt;, private C_fields&lt;true&gt; { friend class const_C_base&lt;const_C&gt;; }; class C : public C_base&lt;C&gt;, private C_fields&lt;false&gt; { friend class C_base&lt;C&gt;; }; </code></pre> <p>If you actually have few fields, it may be easier to duplicate them in both classes rather than going for a struct. If there are many, but they are all of the same type, then it is simpler to pass that type as a type parameter directly, and not bother with <code>const</code> wrapper template.</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. 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.
 

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