Conditions for copy elision?
<p>I wanted to verify the if the following optimizations work as expected:</p>

<ul>
<li>RVO</li>
<li>Named RVO</li>
<li>Copy elision when passing an argument by value</li>
</ul>

<p>So I wrote this little program:</p>

<pre><code>#include &lt;algorithm&gt;
#include &lt;cstddef&gt;
#include &lt;iostream&gt;
#include &lt;vector&gt;

struct Foo {
    Foo(std::size_t length, char value) : data(length, value) { }

    Foo(const Foo &amp; rhs) : data(rhs.data) { std::cout &lt;&lt; "*** COPY ***" &lt;&lt; std::endl; }

    Foo &amp; operator= (Foo rhs) {
        std::cout &lt;&lt; "*** ASSIGNMENT ***" &lt;&lt; std::endl;
        std::swap(data, rhs.data); // probably expensive, ignore this please
        return *this;
    }

    ~Foo() { }

    std::vector&lt;char&gt; data;
};

Foo TestRVO() { return Foo(512, 'r'); }

Foo TestNamedRVO() { Foo result(512, 'n'); return result; }

void PassByValue(Foo inFoo) {}

int main()
{
    std::cout &lt;&lt; "\nTest RVO: " &lt;&lt; std::endl;
    Foo rvo = TestRVO();

    std::cout &lt;&lt; "\nTest named RVO: " &lt;&lt; std::endl;
    Foo named_rvo = TestNamedRVO();

    std::cout &lt;&lt; "\nTest PassByValue: " &lt;&lt; std::endl;
    Foo foo(512, 'a');
    PassByValue(foo);

    std::cout &lt;&lt; "\nTest assignment: " &lt;&lt; std::endl;
    Foo f(512, 'f');
    Foo g(512, 'g');
    f = g;
}
</code></pre>

<p>And I compiled it with optimizations enabled:</p>

<pre><code>$ g++ -o test -O3 main.cpp ; ./test
</code></pre>

<p>This is output:</p>

<pre><code>Test RVO: 

Test named RVO: 

Test PassByValue: 
*** COPY ***

Test assignment: 
*** COPY ***
*** ASSIGNMENT ***
</code></pre>

<p>According to the output RVO and named RVO work as expected. However, copy elision is not performed for the assignment operator and when calling <code>PassByValue</code>.</p>

<p>Is copy elision not allowed on user defined copy-constructors? (I know that RVO is explicitly allowed by the standard but I don't know about copy elision when passing by value.) Is there a way to verify copy elision without defining copy constructors?</p>
