Note that there are some explanatory texts on larger screens.

plurals
  1. POReference-type conversion operators: asking for trouble?
    text
    copied!<p>When I compile the following code using <code>g++</code></p> <pre><code>class A {}; void foo(A&amp;) {} int main() { foo(A()); return 0; } </code></pre> <p>I get the following error messages:</p> <pre><code>&gt; g++ test.cpp -o test test.cpp: In function ‘int main()’: test.cpp:10: error: invalid initialization of non-const reference of type ‘A&amp;’ from a temporary of type ‘A’ test.cpp:6: error: in passing argument 1 of ‘void foo(A&amp;)’ </code></pre> <p>After some reflection, these errors make plenty of sense to me. <code>A()</code> is just a temporary value, not an assignable location on the stack, so it wouldn't seem to have an address. If it doesn't have an address, then I can't hold a reference to it. Okay, fine.</p> <p>But wait! If I add the following conversion operator to the class <code>A</code></p> <pre><code>class A { public: operator A&amp;() { return *this; } }; </code></pre> <p>then all is well! My question is whether this even remotely safe. What exactly does <code>this</code> point to when <code>A()</code> is constructed as a temporary value?</p> <p>I am given some confidence by the fact that</p> <pre><code>void foo(const A&amp;) {} </code></pre> <p>can accept temporary values according to <code>g++</code> and all other compilers I've used. The <code>const</code> keyword can always be cast away, so it would surprise me if there were any actual semantic differences between a <code>const A&amp;</code> parameter and an <code>A&amp;</code> parameter. So I guess that's another way of asking my question: why is a <code>const</code> reference to a temporary value considered safe by the compiler whereas a non-<code>const</code> reference is not?</p>
 

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