<?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[Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben..]]></title><description><![CDATA[<p>Hallo,</p>
<p>also ich weiß ja, dass man temporäre Objekte eigentlich nicht per Referenz zurückgeben soll.<br />
Nur ist dieser Fall vielleicht eine Ausnahme? Wüsste nicht warum, aber frage halt mal.<br />
Ich möchte, dass diese Funktion so aufgerufen werden kann, dass der Parameter direkt verändert wird, aber auch zurückgegeben wird.<br />
Doch sie soll auch für konstante Objekte aufgerufen werden können..<br />
Und muss man da unbedingt std::wstring(ws) schreiben, oder gibt es andere Möglichkeiten?</p>
<pre><code>std::wstring&amp; ExtractFileName(std::wstring&amp; filePathName)
{
	return filePathName.erase(0, filePathName.find_last_of(L'\\') + 1);
}

int main()
{
	const std::wstring ws = L&quot;C:\\dir\\file.dat&quot;;

	std::wcout &lt;&lt; ExtractFileName(std::wstring(ws)); // hmm
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/325723/temporäres-objekt-modifizieren-amp-ref-zurückgeben</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Jul 2026 20:49:25 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/325723.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 15 May 2014 10:24:27 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Thu, 15 May 2014 10:24:27 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>also ich weiß ja, dass man temporäre Objekte eigentlich nicht per Referenz zurückgeben soll.<br />
Nur ist dieser Fall vielleicht eine Ausnahme? Wüsste nicht warum, aber frage halt mal.<br />
Ich möchte, dass diese Funktion so aufgerufen werden kann, dass der Parameter direkt verändert wird, aber auch zurückgegeben wird.<br />
Doch sie soll auch für konstante Objekte aufgerufen werden können..<br />
Und muss man da unbedingt std::wstring(ws) schreiben, oder gibt es andere Möglichkeiten?</p>
<pre><code>std::wstring&amp; ExtractFileName(std::wstring&amp; filePathName)
{
	return filePathName.erase(0, filePathName.find_last_of(L'\\') + 1);
}

int main()
{
	const std::wstring ws = L&quot;C:\\dir\\file.dat&quot;;

	std::wcout &lt;&lt; ExtractFileName(std::wstring(ws)); // hmm
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2399273</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399273</guid><dc:creator><![CDATA[codebase!]]></dc:creator><pubDate>Thu, 15 May 2014 10:24:27 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Thu, 15 May 2014 11:00:31 GMT]]></title><description><![CDATA[<p>Bist du dir sicher, dass da eine Referenz auf ein lokales/temporäres Objekt zurückgegeben wird?<br />
Auf der anderen Seite, bist du dir im Klaren darüber, was das hier macht?!</p>
<pre><code>ExtractFileName(std::wstring(ws))
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2399277</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399277</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Thu, 15 May 2014 11:00:31 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Thu, 15 May 2014 11:01:02 GMT]]></title><description><![CDATA[<p>Du hast ja kein temporäres Objekt in der Funktion. Das Objekt ist außerhalb, von daher kann man die Referenz auch wieder zurückgeben.<br />
Allerdings geht es nicht, wenn das Objekt konstant ist, weil erase es verändert. Das erfordert zwingend ein <code>std::wstring&amp; filePathName</code> und der Compiler wird meckern, wenn filePathName konstant ist.<br />
Sonst musst du wirklich eine Kopie erstellen und zurückgeben, dann geht auch keine Referenz als return-typ mehr.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399278</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399278</guid><dc:creator><![CDATA[minastaros]]></dc:creator><pubDate>Thu, 15 May 2014 11:01:02 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Thu, 15 May 2014 11:03:50 GMT]]></title><description><![CDATA[<p>Mir fällt in deiner Funktion kein Fehler oder Problem auf. Deinen Aufruf lässt allerdings nur VS durch, ein Standardkonformer Compiler lässt hier kein temporäres Objekt zu.</p>
<blockquote>
<p>Ich möchte, dass diese Funktion so aufgerufen werden kann, dass der Parameter direkt verändert wird, aber auch zurückgegeben wird.<br />
Doch sie soll auch für konstante Objekte aufgerufen werden können..</p>
</blockquote>
<p>Selbstverständlich kannst du eine Konstante nicht verändern, deine Anforderung ist also unsinnig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399279</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399279</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Thu, 15 May 2014 11:03:50 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Thu, 15 May 2014 11:22:18 GMT]]></title><description><![CDATA[<p>codebase! schrieb:</p>
<blockquote>
<pre><code>int main()
{
	const std::wstring ws = L&quot;C:\\dir\\file.dat&quot;;

	std::wcout &lt;&lt; ExtractFileName(std::wstring(ws)); // hmm
}
</code></pre>
</blockquote>
<p>Dein Hauptproblem ist ein anderes: die Funktion ist soweit in Ordnung. Was du hinter dem wcout machst, ist falsch: du erzeugst ja eine nicht-const Kopie des Strings, deren Lebenszeit außerhalb von ExtractFileName() jedoch nicht garantiert ist, und wcout ggf. auf illegalen Speicher zugreift.<br />
Wenn du das Objekt vorher erzeugst, lebt es noch bei wcout.</p>
<p>Der sematisch richtigere Weg wäre eher, dass ExtractFileName() die Kopie selbst erzeugt und zurückgibt, dann wird auch der Aufruf klarer. Warum? Der Name &quot;extract&quot; suggeriert, dass der ursprüngliche Dateipfad zumindest in Teilen irgendwo weiterlebt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399282</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399282</guid><dc:creator><![CDATA[minastaros]]></dc:creator><pubDate>Thu, 15 May 2014 11:22:18 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Thu, 15 May 2014 12:00:57 GMT]]></title><description><![CDATA[<p>minastaros schrieb:</p>
<blockquote>
<p>Was du hinter dem wcout machst, ist falsch: du erzeugst ja eine nicht-const Kopie des Strings, deren Lebenszeit außerhalb von ExtractFileName() jedoch nicht garantiert ist, und wcout ggf. auf illegalen Speicher zugreift.</p>
</blockquote>
<p>Ok, genau das war nämlich meine Befürchtung...</p>
<p>Also dann gebe ich besser eine Kopie zurück, und wenn ich die Funktion mit einem konstanten String/Referenz aufrufen will, muss ich eben &quot;std::wstring(ws)&quot; übergeben, ansonsten eben nur den nicht-konstanten String.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399287</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399287</guid><dc:creator><![CDATA[codebase!]]></dc:creator><pubDate>Thu, 15 May 2014 12:00:57 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Thu, 15 May 2014 14:21:44 GMT]]></title><description><![CDATA[<p>Warum nicht zwei Funktionen? Eine, die eine Kopie macht und die andere, die in-place ändert. Das sorgt für viel weniger Verwirrung.</p>
<pre><code>void inplace(std::wstring&amp; s)
{
   ...
}

std::wstring copy(std::wstring s)
{
    inplace(s);
    return s;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2399317</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399317</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 15 May 2014 14:21:44 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Thu, 15 May 2014 20:24:59 GMT]]></title><description><![CDATA[<p>codebase! schrieb:</p>
<blockquote>
<p>... muss ich eben &quot;std::wstring(ws)&quot; übergeben, ansonsten eben nur den nicht-konstanten String.</p>
</blockquote>
<p>Nee, genau das nicht! Du kannst kein temporäres Objekt allein als Funktionsargument übergeben, weil es nur innerhalb der beiden Klammern vom ExtractFileName()-Aufruf lebt und außerhalb nicht mehr. Eher sowas:</p>
<pre><code>std::wstring ExtractFileName(std::wstring filePathName)  // hier wird kopiert (ohne &amp;)
{
    return filePathName.erase(0, filePathName.find_last_of(L'\\') + 1);
}

int main()
{
    const std::wstring ws = L&quot;C:\\dir\\file.dat&quot;;

    std::wcout &lt;&lt; ExtractFileName(ws);    // geht, weil die Funktion eine Kopie erzeugt - und _diese_ kürzt
}
</code></pre>
<p>oder ein temporäres Objekt _vor_ dem wcout:</p>
<pre><code>std::wstring&amp; ExtractFileName(std::wstring&amp; filePathName)
{
    return filePathName.erase(0, filePathName.find_last_of(L'\\') + 1);
}

int main()
{
    const std::wstring ws = L&quot;C:\\dir\\file.dat&quot;;

    std::string nonConstStr(ws);    // hier ist das temporäre Objekt - aber es überlebt das wcout! 
    std::wcout &lt;&lt; ExtractFileName(nonConstStr);
}
</code></pre>
<p>Oder eben Nexus' Ansatz...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399380</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399380</guid><dc:creator><![CDATA[minastaros]]></dc:creator><pubDate>Thu, 15 May 2014 20:24:59 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Thu, 15 May 2014 20:52:11 GMT]]></title><description><![CDATA[<p>minastaros schrieb:</p>
<blockquote>
<p>Du kannst kein temporäres Objekt allein als Funktionsargument übergeben, weil es nur innerhalb der beiden Klammern vom ExtractFileName()-Aufruf lebt und außerhalb nicht mehr.</p>
</blockquote>
<p>Genau genommen lebt es während des ganzen Ausdrucks, also bis zum Semikolon. Das kann einen Unterschied machen, weil z.B.</p>
<pre><code>OtherFunction(ExtractFileName(temporary));
</code></pre>
<p>funktioniert,</p>
<pre><code>std::wstring&amp; s = ExtractFileName(temporary);
OtherFunction(s);
</code></pre>
<p>hingegen nicht (mal ausser Acht gelassen, dass man eh keine Temporaries an Non-Const-LValue-Referenzen binden kann).</p>
<p>Die Situation ist mir in der Praxis vor allem mit <code>c_str()</code> begegnet, wo ich mich immer gefragt habe, wie lange der lebt, wenn der String dahinter selbst temporär ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399383</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399383</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 15 May 2014 20:52:11 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Fri, 16 May 2014 09:01:58 GMT]]></title><description><![CDATA[<p>codebase! schrieb:</p>
<blockquote>
<p>also ich weiß ja, dass man temporäre Objekte eigentlich nicht per Referenz zurückgeben soll.<br />
Nur ist dieser Fall vielleicht eine Ausnahme?</p>
</blockquote>
<p>Wenn der Code bei Dir überhaupt so kompiliert, dann nutzt Du wahrscheinlich ein &quot;Feature&quot; von Microsoft aus, was Dir das Initialisieren einer Lvalue-Referenz mit einem temporären Objekt erlaubt; denn das ist kein Standard-C++. In Standard-C++ ist das absichtlich nicht erlaubt.</p>
<p>Abgesehen davon, wäre es nur dann eine Ausnahme, wenn Du mit diesem Ansatz wirklich etwas gewinnen würdest. Ich sehe aber nur die Gefahr des Missbrauchs. Zum Beispiel wird das hier</p>
<pre><code class="language-cpp">for (auto c : ExtractFileName(std::wstring(ws))) {
    cout &lt;&lt; c;
}
cout &lt;&lt; endl;
</code></pre>
<p>in Deinem Fall undefiniertes Verhalten hervorrufen, weil das temporäre <code>wstring</code> -Objekt nicht lang genug lebt. Einen Vorteil sehe ich nicht. Du hättest auch einfach das hier schreiben können:</p>
<pre><code>std::wstring ExtractFileName(std::wstring filePathName)
{
    filePathName.erase(0, filePathName.find_last_of(L'\\') + 1);
    return filePathName;
}
</code></pre>
<p>Man beachte: Weder Rückgabe noch Parameter ist eine Referenz. Außerdem habe ich hier absichtlich das <code>return</code> vom <code>erase</code> getrennt, weil so das <code>wstring</code> -Objekt implizit &quot;gemoved&quot; wird. Alternativ hätte man dafür <code>std::move</code> benutzen müssen.</p>
<p>Im Vergleich zu Deiner Lösung findet hier nur ein zusätzliches Move statt. Und das ist bei <code>wstring</code> -Objekten billig.</p>
<p>Vielleicht kann ich Dich ja auch für die Programmiersprache Rust begeistern. In Rust ist die Lebenszeit ein Teil des Typsystems. In Rust kann man problemlos Referenzen aus Funktionen zurück geben. Sie müssen nur entsprechend um eine bestimmte Lebenszeitgarantie erweitert werden:</p>
<pre><code>fn extract_filename&lt;'a&gt;(s: &amp;'a str) -&gt; &amp;'a str {
   ...
}
</code></pre>
<p>Hier ist <code>'a</code> ein Lebenszeitparameter und der Typ <code>&amp;str</code> ein String-Slice (effektiv Pointer + Länge). Die Funktion verspricht, ein String-Slice zurück zu geben, was mindestens genauso lange gültig bleibt, wie das übergebene String-Slice. Somit werden &quot;use-after-free&quot;-Fehler zur Compilezeit in Rust ausgeschlossen. Du würdest einfach einen Übersetzungsfehler statt undefiniertes Laufzeitverhalten bekommen. Aber die Sprache ist noch sehr experimentell. Da ändert sich auch gern mal was an der Sprache und/oder Standardbibliothek.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399444</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399444</guid><dc:creator><![CDATA[kkaw]]></dc:creator><pubDate>Fri, 16 May 2014 09:01:58 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Sun, 18 May 2014 18:05:14 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Genau genommen lebt es während des ganzen Ausdrucks, also bis zum Semikolon. Das kann einen Unterschied machen, weil z.B.</p>
<pre><code>OtherFunction(ExtractFileName(temporary));
</code></pre>
<p>funktioniert</p>
</blockquote>
<p>Ah, also hieße das, dass prinzipiell die zu Beginn vom TE erstellte Form sogar funktionieren dürfte? :</p>
<pre><code>std::wcout.operator&lt;&lt;( ExtractFileName(std::wstring(ws)));
</code></pre>
<p>Da hab ich wieder was gelernt, danke. Nichtsdestotrotz würde ich diese Form nicht verwenden, weil alternative Formen klarer sind und die Frage gar nicht erst aufwerfen.<br />
Das im Funktionsaufruf notwendige <code>std::wstring()</code> fühlt sich einfach fehl am Platze an. Dann lieber eine Funktion, die sich auch ohne Krücke sauber aufrufen lässt, also entweder eine eigene Funktion oder eine explizite non-const-Kopie vorher.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399769</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399769</guid><dc:creator><![CDATA[minastaros]]></dc:creator><pubDate>Sun, 18 May 2014 18:05:14 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Sun, 18 May 2014 19:24:40 GMT]]></title><description><![CDATA[<p>minastaros schrieb:</p>
<blockquote>
<p>Ah, also hieße das, dass prinzipiell die zu Beginn vom TE erstellte Form sogar funktionieren dürfte? :</p>
<pre><code>std::wcout.operator&lt;&lt;( ExtractFileName(std::wstring(ws)));
</code></pre>
</blockquote>
<p>Jein. Was NICHT geht: Man kann eine Lvalue-Referenz-auf-nicht-const nicht mit einem temporären Objekt initialisieren. Das ist bzgl Standard-C++ ein Fehler, der zur Compilezeit von jedem vernünftigen Compiler nicht akzeptiert wird.</p>
<p>Aber das temporäre Objekt würde lang genug leben, ja. Eben so lange bis der komplette Ausdruck ausgewertet wurde (quasi beim Semikolon).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399783</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399783</guid><dc:creator><![CDATA[kkaw]]></dc:creator><pubDate>Sun, 18 May 2014 19:24:40 GMT</pubDate></item><item><title><![CDATA[Reply to Temporäres Objekt modifizieren &amp;amp; ref. zurückgeben.. on Sun, 18 May 2014 19:56:47 GMT]]></title><description><![CDATA[<p>kkaw schrieb:</p>
<blockquote>
<p>Wenn der Code bei Dir überhaupt so kompiliert, dann nutzt Du wahrscheinlich ein &quot;Feature&quot; von Microsoft aus, was Dir das Initialisieren einer Lvalue-Referenz mit einem temporären Objekt erlaubt; denn das ist kein Standard-C++. In Standard-C++ ist das absichtlich nicht erlaubt.</p>
</blockquote>
<p>kkaw schrieb:</p>
<blockquote>
<p>Das ist bzgl Standard-C++ ein Fehler, der zur Compilezeit von jedem vernünftigen Compiler nicht akzeptiert wird.</p>
</blockquote>
<p>Um mal dem Halbwissen entgegen zu wirken: Bei Visual Studio ist das eine Compiler<strong>erweiterung</strong>, die bei entsprechender Warnstufe eine Warnung hervorruft und sich abschalten lässt.</p>
<p>Etwa ähnlich, wie g++ Variable-Length-Arrays und andere Dinge erlaubt, solange man diese nicht ausdrücklich mit Compilerflags deaktiviert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399791</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399791</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 18 May 2014 19:56:47 GMT</pubDate></item></channel></rss>