<?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[max_element + remove_if für einen const vector]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe einen vector&lt;double&gt; v, der NANs enthalten kann. Aus diesem möchte ich das größte Element haben.</p>
<p>Nun hatte ich mir gedacht, ich gehe in zwei Schritten vor, also zuerst die NANs ausfiltern, dann max_element berechnen.</p>
<p>Also schrieb ich:</p>
<pre><code>auto m = std::max_element(std::remove_if(v.begin(), v.end(), [](double d){return std::isnan(d);}), v.end());
</code></pre>
<p>Nur leider geht das nicht, wenn der vector const ist:</p>
<pre><code>In file included from /usr/include/c++/4.8/algorithm:62:0,
                 from /tmp/test.cpp:1:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = __gnu_cxx::__normal_iterator&lt;const double*, std::vector&lt;double&gt; &gt;; _Predicate = main()::__lambda0]’:
/tmp/test.cpp:11:25:   required from here
/usr/include/c++/4.8/bits/stl_algo.h:1152:23: error: assignment of read-only location ‘__result.__gnu_cxx::__normal_iterator&lt;_Iterator, _Container&gt;::operator*&lt;const double*, std::vector&lt;double&gt; &gt;()’
             *__result = _GLIBCXX_MOVE(*__first);
                       ^
</code></pre>
<p>Warum geht das nicht? Ich will doch nur den Zeiger auf das größte Element und nichts ändern! Und wie könnte man es auf diese Weise zum Funktionieren bringen?</p>
<p>Vollständiges Programm:</p>
<pre><code>#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;limits&gt;
#include &lt;vector&gt;

int main() {
  using namespace std;
  const vector&lt;double&gt; v = {10, numeric_limits&lt;double&gt;::quiet_NaN(), 20};
  auto m = max_element(remove_if(v.begin(), v.end(), [](double d) {
                         return std::isnan(d);
                       }), v.end());
  cout &lt;&lt; *m &lt;&lt; &quot;\n&quot;;
}
</code></pre>
<p>Das Problem selbst habe ich jetzt gelöst, darum geht es mir nicht - ich dachte nur, obige Variante wäre einfacher, da ich unten beim (a&lt;b oder isnan) einmal kurz nachdenken musste:</p>
<pre><code>auto max_it = std::max_element(y_.begin(), y_.end(), [](double a, double b) { return a &lt; b || std::isnan(a); });
</code></pre>
<p>(Unterschiede für &quot;nur nans im vector&quot; mal ignoriert)</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/337584/max_element-remove_if-für-einen-const-vector</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Apr 2026 23:25:48 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/337584.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 12 Apr 2016 16:35:04 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to max_element + remove_if für einen const vector on Tue, 12 Apr 2016 16:35:04 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe einen vector&lt;double&gt; v, der NANs enthalten kann. Aus diesem möchte ich das größte Element haben.</p>
<p>Nun hatte ich mir gedacht, ich gehe in zwei Schritten vor, also zuerst die NANs ausfiltern, dann max_element berechnen.</p>
<p>Also schrieb ich:</p>
<pre><code>auto m = std::max_element(std::remove_if(v.begin(), v.end(), [](double d){return std::isnan(d);}), v.end());
</code></pre>
<p>Nur leider geht das nicht, wenn der vector const ist:</p>
<pre><code>In file included from /usr/include/c++/4.8/algorithm:62:0,
                 from /tmp/test.cpp:1:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = __gnu_cxx::__normal_iterator&lt;const double*, std::vector&lt;double&gt; &gt;; _Predicate = main()::__lambda0]’:
/tmp/test.cpp:11:25:   required from here
/usr/include/c++/4.8/bits/stl_algo.h:1152:23: error: assignment of read-only location ‘__result.__gnu_cxx::__normal_iterator&lt;_Iterator, _Container&gt;::operator*&lt;const double*, std::vector&lt;double&gt; &gt;()’
             *__result = _GLIBCXX_MOVE(*__first);
                       ^
</code></pre>
<p>Warum geht das nicht? Ich will doch nur den Zeiger auf das größte Element und nichts ändern! Und wie könnte man es auf diese Weise zum Funktionieren bringen?</p>
<p>Vollständiges Programm:</p>
<pre><code>#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;limits&gt;
#include &lt;vector&gt;

int main() {
  using namespace std;
  const vector&lt;double&gt; v = {10, numeric_limits&lt;double&gt;::quiet_NaN(), 20};
  auto m = max_element(remove_if(v.begin(), v.end(), [](double d) {
                         return std::isnan(d);
                       }), v.end());
  cout &lt;&lt; *m &lt;&lt; &quot;\n&quot;;
}
</code></pre>
<p>Das Problem selbst habe ich jetzt gelöst, darum geht es mir nicht - ich dachte nur, obige Variante wäre einfacher, da ich unten beim (a&lt;b oder isnan) einmal kurz nachdenken musste:</p>
<pre><code>auto max_it = std::max_element(y_.begin(), y_.end(), [](double a, double b) { return a &lt; b || std::isnan(a); });
</code></pre>
<p>(Unterschiede für &quot;nur nans im vector&quot; mal ignoriert)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492987</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492987</guid><dc:creator><![CDATA[wob]]></dc:creator><pubDate>Tue, 12 Apr 2016 16:35:04 GMT</pubDate></item><item><title><![CDATA[Reply to max_element + remove_if für einen const vector on Tue, 12 Apr 2016 16:46:32 GMT]]></title><description><![CDATA[<p><code>remove_if</code> strukturiert den <code>vector</code> so um, dass alle das Prädikat nicht erfüllenden Elemente am Ende stehen. Der Rückgabewert ist ein Iterator auf das erste dieser Elemente. Diese Lösung ist natürlich, selbst wenn möglich, deutlich ineffizienter als deine zweite.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492988</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492988</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Tue, 12 Apr 2016 16:46:32 GMT</pubDate></item><item><title><![CDATA[Reply to max_element + remove_if für einen const vector on Tue, 12 Apr 2016 17:08:41 GMT]]></title><description><![CDATA[<p>Übrigens ist dein Code nach wie vor nicht so effizient wie er sein könnte.</p>
<pre><code>template &lt;typename InputIt&gt;
auto max(InputIt first, InputIt last) {
    using type = typename std::iterator_traits&lt;InputIt&gt;::value_type;
    static_assert( std::numeric_limits&lt;type&gt;::is_iec559 );
    first = std::find_if(first, last, [] (float f) {return not std::isnan(f);});
    auto cur = *first;
    if (first == last) return std::numeric_limits&lt;type&gt;::quiet_NaN();
    while (++first != last)
        if (cur &lt; *first) // Falls isnan(*first), ist der Vergleich false
            cur = *first;
    return cur;
}
</code></pre>
<p><a href="http://coliru.stacked-crooked.com/a/2101b0354e8cb390" rel="nofollow">Demo</a>.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492992</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492992</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Tue, 12 Apr 2016 17:08:41 GMT</pubDate></item><item><title><![CDATA[Reply to max_element + remove_if für einen const vector on Tue, 12 Apr 2016 18:18:43 GMT]]></title><description><![CDATA[<p>Meine Güte, ich war verwirrt und irgendwie der Meinung, dass remove_if den unterliegenden vector nicht ändert (benutze das normalerweise nur mit erase zusammen). Was ich eigentlich haben wollte, ist sowas wie <code>boost::make_filter_iterator</code> ! Sieht aber irgendwie komplizierter aus als die jetzige Lösung.</p>
<p>Das ganze ist bei mir ein einem völlig unkritischen Codeteil. Bevor ich da an Performance denke, muss ich mir lieber erst mal überlegen, ob ich bei nur NaN im vector nicht lieber v.end() als Ergebnis vom nan-aware max_element haben will statt NaN...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2492996</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2492996</guid><dc:creator><![CDATA[wob]]></dc:creator><pubDate>Tue, 12 Apr 2016 18:18:43 GMT</pubDate></item></channel></rss>