<?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[temporary als non-const-ref übergeben]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich benutze die Bibliothek Eigen für Matrizen und Vektoren und habe eine Funktion geschrieben, die die Werte eines solchen Vektors inplace verändert.<br />
Oft will ich aber nicht den gesamten Vektor an die Funktion übergeben, sondern nur einen Teil (Segment) des Vektors, wofür Eigen eine nützliche segment()-Methode anbietet.<br />
Der Rückgabewert von segment() ein ConstSegmentReturnType (typedef) ist, also Rückgabe eines art proxy-objekts per Wert.<br />
Meine Funktion die einen Vektor inplace bearbeitet sieht sinngemäß so aus (laut einem Eigentutorial soll man Eigen::DenseBase als Typ verwenden, wenn man auch Segmente als Eingabe erlauben will):</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
void inplaceF(Eigen::DenseBase&lt;T&gt;&amp; v)
{
	for(int i = 0; i &lt; v.size(); ++i)
	{
		v(i)++;
	}
}
</code></pre>
<p>Das Problem ist nun, dass bei einem Aufruf</p>
<pre><code class="language-cpp">inplaceF(v.segment(0,1000));
</code></pre>
<p>zunächst ein temporäres (proxy)-Objekt zurückgegeben wird, dass dann beim Aufruf der Funktion an eine nicht-const-Referenz gebunden wird, was (afaik) laut Standard nicht erlaubt ist.</p>
<p>Um das zu beheben habe ich bisher nur diese (unschöne) Möglichkeit gefunden (ungetestet):</p>
<pre><code class="language-cpp">SegmentReturnType dummy = v.segment(0,1000);
inplaceF(dummy);
</code></pre>
<p>Kennt ihr eine gute Möglichkeit, das zu beheben?<br />
Natürlich könnte man jetzt auch sagen, dann soll die Funktion eben nicht inplace arbeiten, aber das möchte ich nunmal so haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/318013/temporary-als-non-const-ref-übergeben</link><generator>RSS for Node</generator><lastBuildDate>Mon, 27 Jul 2026 21:39:46 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/318013.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 27 Jun 2013 21:32:50 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to temporary als non-const-ref übergeben on Thu, 27 Jun 2013 21:37:53 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich benutze die Bibliothek Eigen für Matrizen und Vektoren und habe eine Funktion geschrieben, die die Werte eines solchen Vektors inplace verändert.<br />
Oft will ich aber nicht den gesamten Vektor an die Funktion übergeben, sondern nur einen Teil (Segment) des Vektors, wofür Eigen eine nützliche segment()-Methode anbietet.<br />
Der Rückgabewert von segment() ein ConstSegmentReturnType (typedef) ist, also Rückgabe eines art proxy-objekts per Wert.<br />
Meine Funktion die einen Vektor inplace bearbeitet sieht sinngemäß so aus (laut einem Eigentutorial soll man Eigen::DenseBase als Typ verwenden, wenn man auch Segmente als Eingabe erlauben will):</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
void inplaceF(Eigen::DenseBase&lt;T&gt;&amp; v)
{
	for(int i = 0; i &lt; v.size(); ++i)
	{
		v(i)++;
	}
}
</code></pre>
<p>Das Problem ist nun, dass bei einem Aufruf</p>
<pre><code class="language-cpp">inplaceF(v.segment(0,1000));
</code></pre>
<p>zunächst ein temporäres (proxy)-Objekt zurückgegeben wird, dass dann beim Aufruf der Funktion an eine nicht-const-Referenz gebunden wird, was (afaik) laut Standard nicht erlaubt ist.</p>
<p>Um das zu beheben habe ich bisher nur diese (unschöne) Möglichkeit gefunden (ungetestet):</p>
<pre><code class="language-cpp">SegmentReturnType dummy = v.segment(0,1000);
inplaceF(dummy);
</code></pre>
<p>Kennt ihr eine gute Möglichkeit, das zu beheben?<br />
Natürlich könnte man jetzt auch sagen, dann soll die Funktion eben nicht inplace arbeiten, aber das möchte ich nunmal so haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2334884</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2334884</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Thu, 27 Jun 2013 21:37:53 GMT</pubDate></item><item><title><![CDATA[Reply to temporary als non-const-ref übergeben on Thu, 27 Jun 2013 23:06:26 GMT]]></title><description><![CDATA[<p>Überladung für rvalues anbieten</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
void inplaceF(Eigen::DenseBase&lt;T&gt;&amp;&amp; v)
{
    inplaceF(v);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2334891</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2334891</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 27 Jun 2013 23:06:26 GMT</pubDate></item><item><title><![CDATA[Reply to temporary als non-const-ref übergeben on Fri, 28 Jun 2013 08:15:50 GMT]]></title><description><![CDATA[<p>was natürlich nur unter C++0x funktioniert *seufz*. Es löst das Problem auch nicht direkt, da es nicht für alle temporären objekte sinnvoll ist (temporärer Vektor/temporäre Matrix). Da würde man schon gerne haben, dass der Compiler nicht schweigt.</p>
<p>Ich schlage mich auch mit dem Problem rum. Kurz gefasst: wenn dir Eigen nicht hilft, musst du immer irgendwelche Konstrukte dieser Art verwenden.</p>
<p>Wenn dir der explizite dummy zu viel Aufwand ist, zum Beispiel weil die Funktion häufig aufgerufen wird, ginge vielleicht noch sowas:</p>
<pre><code>template&lt;class T&gt;
struct Proxy:public T{
    Proxy(T const&amp; t):T(t){}
};
template&lt;class T&gt;
Proxy&lt;T&gt; proxy(T const&amp; t){ return Proxy&lt;T&gt;(t);}

//normale implmentation
template&lt;typename T&gt;
void inplaceF(Eigen::DenseBase&lt;T&gt;&amp; v)
{
//...
}

//überladung für proxies
template&lt;typename T&gt;
void inplaceF(Proxy&lt;T&gt; v)
{
    inplaceF(v);
}

//anwendung:
inplaceF(proxy(v.segment(0,1000)))
</code></pre>
<p>//edit besserer Name</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2334936</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2334936</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Fri, 28 Jun 2013 08:15:50 GMT</pubDate></item><item><title><![CDATA[Reply to temporary als non-const-ref übergeben on Fri, 28 Jun 2013 08:15:55 GMT]]></title><description><![CDATA[<p>Microsoft Compiler erlauben das Binden temporaerer Objekte an non-const-Referenzen</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2334938</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2334938</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Fri, 28 Jun 2013 08:15:55 GMT</pubDate></item><item><title><![CDATA[Reply to temporary als non-const-ref übergeben on Fri, 28 Jun 2013 10:24:42 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Überladung für rvalues anbieten</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
void inplaceF(Eigen::DenseBase&lt;T&gt;&amp;&amp; v)
{
    inplaceF(v);
}
</code></pre>
</blockquote>
<p>Danke, funktioniert super.<br />
Einziger Nachteil, wie otze schon geschrieben hat, dass jetzt auch richtige temporäre Matrizen/Vektoren darauf binden können, aber ich glaube das kann ich verkraften, finde ich besser als das immer mit Proxy wrappen zu müssen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2334972</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2334972</guid><dc:creator><![CDATA[*Q* 1]]></dc:creator><pubDate>Fri, 28 Jun 2013 10:24:42 GMT</pubDate></item><item><title><![CDATA[Reply to temporary als non-const-ref übergeben on Fri, 28 Jun 2013 12:59:18 GMT]]></title><description><![CDATA[<p>Kann man da nicht per SFINAE irgendwie die zweite Überladung ausschließen, wenn der Typ keine Referenz-Semantik hat? Es gibt ja die &quot;container&quot;-Typen und diese Proxies, die auf die Elemente nur verweisen. Dass man im ersten Fall inplaceF für temporäre Objekte verbieten will, macht ja Sinn.</p>
<p>Ich habe Eigen bisher nur oberflächlich verwendet. Mir ist klar, dass da einiges and Template-Magie drin steckt und das lässt mich bzgl Aliasing aufpassen. Aber das war's auch schon.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2335004</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2335004</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Fri, 28 Jun 2013 12:59:18 GMT</pubDate></item></channel></rss>