<?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[Bestimmte Elemente aus Container kopieren, anhand beliebig vielen Prädikaten]]></title><description><![CDATA[<p>Hi,<br />
ich habe einen Container mit vielen Elementen, wobei ich aber letztendlich nur eine handvoll Elemente brauche. Nun will ich eine allgemeine Funktion, die mir uninteressante Elemente aussortiert. Ob ein Element aussortiert wird oder nicht, ist von beliebig vielen Funktionen abhängig.</p>
<p>Beispiel: Ein <code>std::set</code> mit mehreren <code>std::string</code> . Nun brauche ich aber nur die Strings, deren Länge genau 6 ist und die nur aus Ziffern bestehen.</p>
<p>1. Versuch: Zuerst dachte ich an eine Funktion, die beliebig viele <code>std::function</code> entgegennehmen kann, mittels <code>variadic templates</code> . Das ging aber nicht, weil VS 2012 das nicht unterstützt (ich habe nur VS 2012 zur Verfügung).</p>
<p>2. Versuch: <code>std::tuple</code> mit beliebig viele <code>std::function</code> , wobei durch <code>_VARIADIC_MAX 10</code> simuliert wird. Da hatte ich dann das Problem, dass ich nicht über <code>std::tuple</code> iterieren kann, weil <code>I</code> in <code>std::get&lt;I&gt;</code> nicht zur Compilezeit bekannt ist.</p>
<p>3. Versuch: Alle <code>std::function</code> in einen <code>std::vector</code> stecken:</p>
<pre><code>#include &lt;algorithm&gt;
#include &lt;cctype&gt;
#include &lt;functional&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;set&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
using namespace std;

bool correct_length( const std::string&amp; str )
{
	return str.length()==6;
}

bool only_digits( const std::string&amp; str )
{
    return all_of( begin(str), end(str), isdigit );
}

template &lt;typename InputIterator, typename OutputIterator, typename Functions&gt;
void copy_needed(  InputIterator first, InputIterator last, OutputIterator result, const Functions&amp; functions )
{
	while( first!=last )
	{
		bool needed = true;
		for(const auto&amp; func : functions)
			needed = needed &amp;&amp; func(*first);

		if( needed )
		{
			*result = *first;
			++result;
		}
		++first;
	}
}

int main()
{
	typedef string value_type;

	set&lt;value_type&gt; strs;
	strs.insert( &quot;1x&quot; );
	strs.insert( &quot;12&quot; );
	strs.insert( &quot;123x&quot; );
	strs.insert( &quot;1234&quot; );
	strs.insert( &quot;12345x&quot; );
	strs.insert( &quot;123456&quot; );
	strs.insert( &quot;123456x&quot; );
	strs.insert( &quot;1234567&quot; );

	vector&lt;function&lt;bool(const value_type&amp;)&gt;&gt; functions;
	functions.push_back( function&lt;bool(const value_type&amp;)&gt;(correct_length) );
	functions.push_back( function&lt;bool(const value_type&amp;)&gt;(only_digits) );

	set&lt;value_type&gt; needed_strs;

	copy_needed( begin(strs), end(strs), inserter(needed_strs,begin(needed_strs)), functions );

	for(const auto&amp; str : needed_strs)
		cout &lt;&lt; str &lt;&lt; '\n';
}
</code></pre>
<p>Irgendwie gefällt mir die Lösung aber nicht. Ist die Herangehensweise überhaupt richtig? Hat jemand eine schönere Lösung?</p>
<p>Danke im Voraus.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/322692/bestimmte-elemente-aus-container-kopieren-anhand-beliebig-vielen-prädikaten</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Jul 2026 16:49:18 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/322692.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 03 Jan 2014 19:20:31 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Bestimmte Elemente aus Container kopieren, anhand beliebig vielen Prädikaten on Fri, 03 Jan 2014 19:20:31 GMT]]></title><description><![CDATA[<p>Hi,<br />
ich habe einen Container mit vielen Elementen, wobei ich aber letztendlich nur eine handvoll Elemente brauche. Nun will ich eine allgemeine Funktion, die mir uninteressante Elemente aussortiert. Ob ein Element aussortiert wird oder nicht, ist von beliebig vielen Funktionen abhängig.</p>
<p>Beispiel: Ein <code>std::set</code> mit mehreren <code>std::string</code> . Nun brauche ich aber nur die Strings, deren Länge genau 6 ist und die nur aus Ziffern bestehen.</p>
<p>1. Versuch: Zuerst dachte ich an eine Funktion, die beliebig viele <code>std::function</code> entgegennehmen kann, mittels <code>variadic templates</code> . Das ging aber nicht, weil VS 2012 das nicht unterstützt (ich habe nur VS 2012 zur Verfügung).</p>
<p>2. Versuch: <code>std::tuple</code> mit beliebig viele <code>std::function</code> , wobei durch <code>_VARIADIC_MAX 10</code> simuliert wird. Da hatte ich dann das Problem, dass ich nicht über <code>std::tuple</code> iterieren kann, weil <code>I</code> in <code>std::get&lt;I&gt;</code> nicht zur Compilezeit bekannt ist.</p>
<p>3. Versuch: Alle <code>std::function</code> in einen <code>std::vector</code> stecken:</p>
<pre><code>#include &lt;algorithm&gt;
#include &lt;cctype&gt;
#include &lt;functional&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;set&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
using namespace std;

bool correct_length( const std::string&amp; str )
{
	return str.length()==6;
}

bool only_digits( const std::string&amp; str )
{
    return all_of( begin(str), end(str), isdigit );
}

template &lt;typename InputIterator, typename OutputIterator, typename Functions&gt;
void copy_needed(  InputIterator first, InputIterator last, OutputIterator result, const Functions&amp; functions )
{
	while( first!=last )
	{
		bool needed = true;
		for(const auto&amp; func : functions)
			needed = needed &amp;&amp; func(*first);

		if( needed )
		{
			*result = *first;
			++result;
		}
		++first;
	}
}

int main()
{
	typedef string value_type;

	set&lt;value_type&gt; strs;
	strs.insert( &quot;1x&quot; );
	strs.insert( &quot;12&quot; );
	strs.insert( &quot;123x&quot; );
	strs.insert( &quot;1234&quot; );
	strs.insert( &quot;12345x&quot; );
	strs.insert( &quot;123456&quot; );
	strs.insert( &quot;123456x&quot; );
	strs.insert( &quot;1234567&quot; );

	vector&lt;function&lt;bool(const value_type&amp;)&gt;&gt; functions;
	functions.push_back( function&lt;bool(const value_type&amp;)&gt;(correct_length) );
	functions.push_back( function&lt;bool(const value_type&amp;)&gt;(only_digits) );

	set&lt;value_type&gt; needed_strs;

	copy_needed( begin(strs), end(strs), inserter(needed_strs,begin(needed_strs)), functions );

	for(const auto&amp; str : needed_strs)
		cout &lt;&lt; str &lt;&lt; '\n';
}
</code></pre>
<p>Irgendwie gefällt mir die Lösung aber nicht. Ist die Herangehensweise überhaupt richtig? Hat jemand eine schönere Lösung?</p>
<p>Danke im Voraus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374931</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374931</guid><dc:creator><![CDATA[out]]></dc:creator><pubDate>Fri, 03 Jan 2014 19:20:31 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmte Elemente aus Container kopieren, anhand beliebig vielen Prädikaten on Fri, 03 Jan 2014 19:34:20 GMT]]></title><description><![CDATA[<p>Einen functor/lambda digitslength6 schreiben?<br />
Oder wenn generischer:<br />
Einen functor schreiben, der alle Prädikate (ggf. in einem vector) via &amp;&amp; verkettet?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374937</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374937</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Fri, 03 Jan 2014 19:34:20 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmte Elemente aus Container kopieren, anhand beliebig vielen Prädikaten on Fri, 03 Jan 2014 19:36:53 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">#include &lt;algorithm&gt;
#include &lt;cctype&gt;
#include &lt;functional&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;set&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
using namespace std;

bool correct_length( const std::string&amp; str )
{
  return str.length()==6;
}

bool only_digits( const std::string&amp; str )
{
  return all_of( begin(str), end(str), ::isdigit );
} 

template &lt;typename A, typename B&gt;
struct and_combined_predicate {
  A *a;
  B *b;
  template &lt;typename T&gt;
  bool operator()(T&amp;&amp; x)
  {
    return (*a)(x) &amp;&amp; (*b)(x);
  }
};

template &lt;typename A, typename B&gt;
and_combined_predicate&lt;A,B&gt; and_combine(A const&amp; a, B const&amp; b)
{
  return and_combined_predicate&lt;A,B&gt;{a,b};
} 

int main()
{
  typedef string value_type;

  set&lt;value_type&gt; strs;
  strs.insert( &quot;1x&quot; );
  strs.insert( &quot;12&quot; );
  strs.insert( &quot;123x&quot; );
  strs.insert( &quot;1234&quot; );
  strs.insert( &quot;12345x&quot; );
  strs.insert( &quot;123456&quot; );
  strs.insert( &quot;123456x&quot; );
  strs.insert( &quot;1234567&quot; );

  set&lt;value_type&gt; needed_strs;

  copy_if( begin(strs), end(strs), inserter(needed_strs,begin(needed_strs)), and_combine(correct_length, only_digits) );

  for(const auto&amp; str : needed_strs)
    cout &lt;&lt; str &lt;&lt; '\n';
}
</code></pre>
<p>???</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374938</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374938</guid><dc:creator><![CDATA[groppy]]></dc:creator><pubDate>Fri, 03 Jan 2014 19:36:53 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmte Elemente aus Container kopieren, anhand beliebig vielen Prädikaten on Fri, 03 Jan 2014 20:09:31 GMT]]></title><description><![CDATA[<p>Nathan schrieb:</p>
<blockquote>
<p>Einen functor/lambda digitslength6 schreiben?</p>
</blockquote>
<p>Das geht nicht. Weil ich zum einen eine Funktionen will, die immer nur 1 Aufgabe erledigen und zum anderen, wenn ich 10 Prädikate habe, dann wäre der Functor-Name irgendwann 50 Zeichen lang.</p>
<p>Nathan schrieb:</p>
<blockquote>
<p>Einen functor schreiben, der alle Prädikate (ggf. in einem vector) via &amp;&amp; verkettet?</p>
</blockquote>
<p>Das wäre dann in <code>groppy</code> s Richtung gedacht, das finde ich schon besser ja.</p>
<p>groppy  schrieb:</p>
<blockquote>
<p>???</p>
</blockquote>
<p>Ja das sieht schon besser aus. Schonmal gut, dass mein <code>copy_needed</code> durch <code>copy_if</code> aus der Standardbibliothek abgelöst wird <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> . Allerdings hast du nur 2 Prädikate beachtet. Es könnten auch 5 oder 10 oder nur 1 sein. Ich glaub da bleibt mir echt nur ein Container übrig, in dem ich alle Prädikate sammle. Ohne <code>variadic templates</code> gehts wohl nicht anders?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374946</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374946</guid><dc:creator><![CDATA[out]]></dc:creator><pubDate>Fri, 03 Jan 2014 20:09:31 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmte Elemente aus Container kopieren, anhand beliebig vielen Prädikaten on Fri, 03 Jan 2014 20:10:14 GMT]]></title><description><![CDATA[<pre><code>#include &lt;functional&gt;
#include &lt;string&gt;
#include &lt;algorithm&gt;
#include &lt;memory&gt;

template&lt;class T&gt;
struct DixiChainer{
	bool operator()(const T &amp;t) const{
		if (nextFunction){
			return f(t) &amp;&amp; (*nextFunction)(t);
		}
		return f(t);
	}
	DixiChainer(std::function&lt;bool(const T&amp;)&gt; f) : f(std::forward&lt;std::function&lt;bool(const T&amp;)&gt;&gt;(f)){}
	DixiChainer &amp;chain(std::function&lt;bool(const T&amp;)&gt; f){
		nextFunction = make_unique&lt;DixiChainer&gt;(std::forward&lt;std::function&lt;bool(const T&amp;)&gt;&gt;(f));
		return *nextFunction;
	}
private:
	std::function&lt;bool(const T&amp;)&gt; f;
	std::unique_ptr&lt;DixiChainer&gt; nextFunction;
};

using namespace std;

bool correct_length(const std::string &amp;str){
	return str.length() == 6;
}

bool only_digits(const std::string &amp;str){
	return all_of(begin(str), end(str), isdigit);
}

int main(){
	DixiChainer&lt;std::string&gt; dc(correct_length);
	dc.chain(only_digits).chain(correct_length).chain(only_digits);
	//hier beliebig viele andere Vergleichsfunktionen anhängen
	bool allgood = dc(&quot;Hallo&quot;);
}
</code></pre>
<p>Man sollte chain noch einen Parameter mitgeben, ob er per &amp;&amp; oder || chainen soll und vielleicht kann man sich auf Funktionen festlegen, sodass man std::function nicht mehr braucht.</p>
<p>@groppy: Könnte/würde man bei dir 4 Funktionen so verbinden?</p>
<pre><code>and_combine(and_combine(and_combine(correct_length, only_digits), correct_length), only_digits);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2374947</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374947</guid><dc:creator><![CDATA[nwp3]]></dc:creator><pubDate>Fri, 03 Jan 2014 20:10:14 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmte Elemente aus Container kopieren, anhand beliebig vielen Prädikaten on Fri, 03 Jan 2014 20:17:55 GMT]]></title><description><![CDATA[<p>nwp3 schrieb:</p>
<blockquote>
<p>@groppy: Könnte/würde man bei dir 4 Funktionen so verbinden?</p>
<pre><code>and_combine(and_combine(and_combine(correct_length, only_digits), correct_length), only_digits);
</code></pre>
</blockquote>
<p>Ja, so war das vorgesehen (falls keine variadischen Templates verfügbar).</p>
<p>Sollte sogar durch den Compiler geinlined werden können, was es ungleich schneller macht als deine Variante.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2374950</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2374950</guid><dc:creator><![CDATA[groppy]]></dc:creator><pubDate>Fri, 03 Jan 2014 20:17:55 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmte Elemente aus Container kopieren, anhand beliebig vielen Prädikaten on Sat, 04 Jan 2014 17:45:08 GMT]]></title><description><![CDATA[<p>Hallo out,</p>
<p>folgendes ist vielleicht von der Syntax her ansprechender:</p>
<pre><code>#include &lt;algorithm&gt;
#include &lt;cctype&gt;
#include &lt;functional&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;set&gt;
#include &lt;string&gt;

using namespace std;

bool correct_length( const std::string&amp; str )
{
    return str.length()==6;
}

bool only_digits( const std::string&amp; str )
{
    return all_of( begin(str), end(str), isdigit );
}

// --   verknüpft zwei Predicate mit gleichem Argumenttyp zu einem (hier logisch AND)
template&lt; typename T &gt;
std::function&lt; bool( const T&amp; ) &gt; operator&amp;&amp;( const std::function&lt; bool( const T&amp; ) &gt;&amp; f1, const std::function&lt; bool( const T&amp; ) &gt;&amp; f2 )
{
    return [=]( const T&amp; x )-&gt; bool
    {
        return f1(x) &amp;&amp; f2(x);
    };
}

int main()
{
    typedef std::string value_type;
    typedef std::function&lt; bool( const value_type&amp; ) &gt; Pred;

    set&lt;value_type&gt; strs;
    strs.insert( &quot;1x&quot; );
    strs.insert( &quot;12&quot; );
    strs.insert( &quot;123x&quot; );
    strs.insert( &quot;1234&quot; );
    strs.insert( &quot;12345x&quot; );
    strs.insert( &quot;123456&quot; );
    strs.insert( &quot;123456x&quot; );
    strs.insert( &quot;1234567&quot; );

    set&lt;value_type&gt; needed_strs;
    copy_if( begin(strs), end(strs), inserter(needed_strs,begin(needed_strs)), 
        Pred(correct_length) &amp;&amp; Pred(only_digits)
    );

    for(const auto&amp; str : needed_strs)
        cout &lt;&lt; str &lt;&lt; '\n';
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2375112</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2375112</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Sat, 04 Jan 2014 17:45:08 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmte Elemente aus Container kopieren, anhand beliebig vielen Prädikaten on Sat, 04 Jan 2014 18:32:26 GMT]]></title><description><![CDATA[<p>nwp3 schrieb:</p>
<blockquote>
<p>@groppy: Könnte/würde man bei dir 4 Funktionen so verbinden?</p>
<pre><code>and_combine(and_combine(and_combine(correct_length, only_digits), correct_length), only_digits);
</code></pre>
</blockquote>
<p>Ah ok, so hat er das gemeint. Auch eine nette Idee, ist mir persönlich aber schon ab 3 Prädikaten schon zu unübersichtlich.</p>
<p>@nwp3: Dein Lösung kann ich noch nicht ganz nachvollziehen, da ich std::forward noch nicht wirklich kenne. Muss ich mir noch genauer anschauen.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/7393">@Werner</a>: Deine Lösung gefällt mir am besten, die werde ich verwenden. Den <code>operator&amp;&amp;</code> zu überladen, auf die Idee wäre ich wohl nie gekommen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> .</p>
<p>Danke euch allen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2375124</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2375124</guid><dc:creator><![CDATA[out]]></dc:creator><pubDate>Sat, 04 Jan 2014 18:32:26 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmte Elemente aus Container kopieren, anhand beliebig vielen Prädikaten on Sun, 05 Jan 2014 03:26:09 GMT]]></title><description><![CDATA[<p>Mit boost::bind ging das auch gut.<br />
Mit boost::lambda wenn ich mich richtig erinnere auch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2375166</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2375166</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sun, 05 Jan 2014 03:26:09 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmte Elemente aus Container kopieren, anhand beliebig vielen Prädikaten on Sun, 05 Jan 2014 13:58:43 GMT]]></title><description><![CDATA[<p><a href="http://cpplinq.codeplex.com/" rel="nofollow">http://cpplinq.codeplex.com/</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2375243</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2375243</guid><dc:creator><![CDATA[boost__linq]]></dc:creator><pubDate>Sun, 05 Jan 2014 13:58:43 GMT</pubDate></item></channel></rss>