Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is pure nasty. First we have to look at the declaration of swap:</p> <pre><code>template&lt;class T&gt; void swap(T &amp;left, T &amp;right); </code></pre> <p>Now, <code>operator[]()</code> on <code>bitset</code> has two overloads:</p> <pre><code>bool operator[](size_type _Pos) const; reference operator[](size_type _Pos); </code></pre> <p>Here <code>reference</code> is <code>bitset::reference</code>, a nested class in <code>bitset</code> that effectively acts as a proxy reference to the one of the underlying bits. What it encapsulates is the <code>bitset</code> and a position in the <code>bitset</code>. Because of the declaration of <code>swap</code>, the second overload is chosen and we are swapping two <code>bitset::reference</code>s. Now here's where it gets nasty. Let's look at a typical implementation of swap:</p> <pre><code>template class&lt;T&gt; swap(T &amp;left, T &amp;right) { T temp = left; left = right; right = temp; } </code></pre> <p>The problem is that <code>left</code> and <code>right</code> are both references to a <code>bitset::reference</code>. They have the same underlying data (because they are proxies; same meaning the both point to the same <code>bitset</code>!) they just encapsulate different positions in that <code>bitset</code>. Thus, think of it like this <code>left</code> is position 0 in some <code>bitset</code> and <code>right</code> is position 1 in some <code>bitset</code> and that <code>bitset</code> is the same <code>bitset</code> as <code>left</code>! Let's forever refer to this <code>bitset</code> as <code>BS</code> (chosen intentionally).</p> <p>So,</p> <pre><code>T temp = left; </code></pre> <p>says that <code>temp</code> is position 0 in <code>BS</code>.</p> <pre><code>left = right; </code></pre> <p>sets position 0 in left to position 1 in <code>BS</code> (which simultaneously changes position 0 in <code>temp</code>!)</p> <pre><code>right = temp; </code></pre> <p>sets position 1 in right to position 0 in <code>BS</code> (which was just set to position 1 in <code>BS</code>!). So at the end of this mess have that position 0 is whatever position 1 was and position 1 is unchanged! Now, because position 0 is the LSB and position 1 is the MSB we have that "10" becomes "11". Ugly.</p> <p>You can get around this with a <a href="http://en.wikipedia.org/wiki/Template_specialization" rel="noreferrer">template specialization</a>:</p> <pre><code>namespace std { template&lt;&gt; void swap&lt;bitset&lt;2&gt;::reference&gt;( bitset&lt;2&gt;::reference &amp;left, bitset&lt;2&gt;::reference &amp;right ) { bool temp = (bool)left; left = (bool)right; right = (bool)temp; } } </code></pre> <p>Then:</p> <pre><code>int main() { bitset&lt;2&gt; test(string("10")); cout &lt;&lt; test; // Prints "10" swap(test[0], test[1]); cout &lt;&lt; test; // Prints "01", hallelujah! } </code></pre>
    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.
 

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