<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[return value optimierung (RVO)-Frage]]></title><description><![CDATA[<p>Hallo,<br />
meiner Meinung nach müsste der Kopierkonstruktor bei temporären Größen wegoptimiert werden. Was ich nicht verstehe ist, warum h3() und h4() sich bezgl. RVO unterschiedlich verhalten:</p>
<pre><code>#include&lt;iostream&gt;
#include&lt;utility&gt;

class A {
public:
  explicit A(int w) : wert(w) {
    std::cout &lt;&lt; &quot;A(int) aufgerufen\n&quot;;    
  }
  A(const A&amp; a)  : wert(a.get()) {
    std::cout &lt;&lt; &quot;A(const A&amp;) aufgerufen\n&quot;; 
  }
  A(A&amp;&amp; a)  : wert(std::move(a.get())) {
    std::cout &lt;&lt; &quot;A(A&amp;&amp;) aufgerufen\n&quot;; 
  }
  A&amp; operator=(const A&amp;) = default;
  A&amp; operator=(A&amp;&amp;) = default;
  int get() const { return wert; }
  A&amp; set(int w)  { wert = w; return *this; }
private:
  int wert;
};

inline A h3() {              // temporary 1, ok: RVO
  return A(17);
}  

inline A h4(const A&amp; a) {   // temporary 2: Wieso kein RVO?
  return (A(a)).set(99); 
}  

inline A h5(const A&amp; a) {   // temporary: ok, move c'tor
  return std::move((A(a)).set(42)); 
}  

int main() {
  A lvalue(5);
  A a1 = h3();
  std::cout &lt;&lt; &quot;h3()  wert = &quot; &lt;&lt; a1.get() &lt;&lt; &quot;\n\n&quot;;  
  int result = h4(lvalue).get();
  std::cout &lt;&lt; &quot;h4(lvalue) wert = &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot;;
  result = h5(lvalue).get();
  std::cout &lt;&lt; &quot;h5(lvalue) wert = &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot;;
}
</code></pre>
<p>Warum wird bei h4() der Kopierkonstruktor zweimal aufgerufen statt nur einmal wie bei h5()?<br />
Bei zurückgegebenen Funktionsparametern erfolgt kein RVO, aber bei h4() wird der Parameter a nicht zurückgegeben, nur verwendet.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/330287/return-value-optimierung-rvo-frage</link><generator>RSS for Node</generator><lastBuildDate>Fri, 03 Jul 2026 10:38:38 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/330287.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 01 Jan 2015 13:44:36 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to return value optimierung (RVO)-Frage on Thu, 01 Jan 2015 13:44:36 GMT]]></title><description><![CDATA[<p>Hallo,<br />
meiner Meinung nach müsste der Kopierkonstruktor bei temporären Größen wegoptimiert werden. Was ich nicht verstehe ist, warum h3() und h4() sich bezgl. RVO unterschiedlich verhalten:</p>
<pre><code>#include&lt;iostream&gt;
#include&lt;utility&gt;

class A {
public:
  explicit A(int w) : wert(w) {
    std::cout &lt;&lt; &quot;A(int) aufgerufen\n&quot;;    
  }
  A(const A&amp; a)  : wert(a.get()) {
    std::cout &lt;&lt; &quot;A(const A&amp;) aufgerufen\n&quot;; 
  }
  A(A&amp;&amp; a)  : wert(std::move(a.get())) {
    std::cout &lt;&lt; &quot;A(A&amp;&amp;) aufgerufen\n&quot;; 
  }
  A&amp; operator=(const A&amp;) = default;
  A&amp; operator=(A&amp;&amp;) = default;
  int get() const { return wert; }
  A&amp; set(int w)  { wert = w; return *this; }
private:
  int wert;
};

inline A h3() {              // temporary 1, ok: RVO
  return A(17);
}  

inline A h4(const A&amp; a) {   // temporary 2: Wieso kein RVO?
  return (A(a)).set(99); 
}  

inline A h5(const A&amp; a) {   // temporary: ok, move c'tor
  return std::move((A(a)).set(42)); 
}  

int main() {
  A lvalue(5);
  A a1 = h3();
  std::cout &lt;&lt; &quot;h3()  wert = &quot; &lt;&lt; a1.get() &lt;&lt; &quot;\n\n&quot;;  
  int result = h4(lvalue).get();
  std::cout &lt;&lt; &quot;h4(lvalue) wert = &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot;;
  result = h5(lvalue).get();
  std::cout &lt;&lt; &quot;h5(lvalue) wert = &quot; &lt;&lt; result &lt;&lt; &quot;\n\n&quot;;
}
</code></pre>
<p>Warum wird bei h4() der Kopierkonstruktor zweimal aufgerufen statt nur einmal wie bei h5()?<br />
Bei zurückgegebenen Funktionsparametern erfolgt kein RVO, aber bei h4() wird der Parameter a nicht zurückgegeben, nur verwendet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435624</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435624</guid><dc:creator><![CDATA[mirko12]]></dc:creator><pubDate>Thu, 01 Jan 2015 13:44:36 GMT</pubDate></item><item><title><![CDATA[Reply to return value optimierung (RVO)-Frage on Thu, 01 Jan 2015 14:10:23 GMT]]></title><description><![CDATA[<p>Hier noch einmal die relevante Standardpassage:</p>
<p>[class.copy]/31 schrieb:</p>
<blockquote>
<p>This elision of copy/move operations, called <em>copy elision</em>, is permitted in the following circumstances (which<br />
may be combined to eliminate multiple copies):</p>
<ul>
<li>in a <code>return</code> statement in a function with a class return type, when the expression is the name of a<br />
non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-<br />
unqualified type as the function return type, the copy/move operation can be omitted by constructing<br />
the automatic object directly into the function’s return value</li>
<li>in a <em>throw-expression</em> […]</li>
<li><strong>when a temporary class object that has not been bound to a reference (12.2) would be copied/moved<br />
to a class object with the same cv-unqualified type, the copy/move operation can be omitted by<br />
constructing the temporary object directly into the target of the omitted copy/move</strong></li>
<li>when the <em>exception-declaration</em> […]</li>
</ul>
</blockquote>
<p>In <code>h4</code> gibst du ein lvalue zurück, eine Referenz. Eine Referenz ist aber keine Temporary. Und ob sie auf ein Objekt verweist das man als Temporary bezeichnen könnte ist irrelevant.</p>
<p>Gemoved wird auch nicht, gerade weil copy elision nicht applikabel ist. Um das zu verhindern kannst du ein C++11 feature anwenden:</p>
<pre><code>A&amp;  set(int w) &amp;  { wert = w; return *this; } 
  A&amp;&amp; set(int w) &amp;&amp; { wert = w; return std::move(*this); }
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2435625</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435625</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Thu, 01 Jan 2015 14:10:23 GMT</pubDate></item><item><title><![CDATA[Reply to return value optimierung (RVO)-Frage on Thu, 01 Jan 2015 15:00:59 GMT]]></title><description><![CDATA[<p>ja, danke. set() gibt eine Referenz <code>A&amp;</code> zurück, kein Objekt. Damit ist die Frage geklärt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2435631</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2435631</guid><dc:creator><![CDATA[mirko12]]></dc:creator><pubDate>Thu, 01 Jan 2015 15:00:59 GMT</pubDate></item></channel></rss>