<?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[Metaprogrammierung: Function-Pointer @Compiletime]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>der Titel klingt zwar etwas komisch, allerdings würde ich gerne einer Template-Funktion übergeben, welche Funktion aufgerufen werden soll. Diese soll bereits zur Compiletime ausgewertet werden.</p>
<p>Also schematisch etwa so:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
void call(const T&amp; t, &lt;functionName&gt;){
	t.&lt;functionName&gt;();
}
</code></pre>
<p>Der Code soll nur verdeutlichen, was ich eigentlich möchte und kann natürlich nicht ansatzweise so funktionieren.</p>
<p>Zur Zeit verwende ich zur Verwirklichung dieses Problems<br />
folgenden Ansatz (hier auch mit zusätzlichen Parametern für den Funktionsaufruf):</p>
<pre><code class="language-cpp">#include &lt;iostream&gt; 

struct Foo{
	void foo(int i) const{
		std::cout &lt;&lt; &quot;Foo::foo int&quot; &lt;&lt; std::endl;
	}
	void foo(double i) const{
		std::cout &lt;&lt; &quot;Foo::foo double&quot; &lt;&lt; std::endl;
	}
	void foo(int i, int j) const{
		std::cout &lt;&lt; &quot;Foo::foo 2*int&quot; &lt;&lt; std::endl;
	}
	void bar() const{
		std::cout &lt;&lt; &quot;Foo::bar&quot; &lt;&lt; std::endl;
	}
};

struct Bar{
	void foo(int i) const{
		std::cout &lt;&lt; &quot;Bar::foo int&quot; &lt;&lt; std::endl;
	}
	void foo(double d) const{
		std::cout &lt;&lt; &quot;Bar::foo double&quot; &lt;&lt; std::endl;
	}
	void bar() const{
		std::cout &lt;&lt; &quot;Bar::bar&quot; &lt;&lt; std::endl;
	}
};

template&lt;typename T&gt;
struct CallFoo{
	template&lt;typename... P&gt;
	static void call(const T&amp; t, P&amp;&amp;... p){
		t.foo(std::forward&lt;P&gt;(p)...);
	}
};

template&lt;typename T&gt;
struct CallBar{
	static void call(const T&amp; t){
		t.bar();
	}
};

template&lt;template&lt;typename&gt; class Func, typename T, typename... P&gt; void call(const T&amp; t, P&amp;&amp;... p){
	Func&lt;T&gt;::call(t, std::forward&lt;P&gt;(p)...);
}

int main(){ 
	Foo foo;
	Bar bar;
	call&lt;CallFoo&gt;(foo, 1);
	call&lt;CallFoo&gt;(foo, 1.0);
	call&lt;CallFoo&gt;(foo, 1, 1);
	call&lt;CallBar&gt;(foo);
	call&lt;CallFoo&gt;(bar, 1);
	call&lt;CallFoo&gt;(bar, 1.0);
	call&lt;CallBar&gt;(bar);
}
</code></pre>
<p>Hier sieht man auch, dass einfache Funktionszeiger nicht mehr ausreichen...</p>
<p>Geht es evtl. eleganter oder habt ihr Alternativvorschläge?</p>
<p>Gruß,<br />
XSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/302083/metaprogrammierung-function-pointer-compiletime</link><generator>RSS for Node</generator><lastBuildDate>Tue, 11 Aug 2026 15:15:38 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/302083.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 10 Apr 2012 23:57:09 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Metaprogrammierung: Function-Pointer @Compiletime on Tue, 10 Apr 2012 23:59:52 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>der Titel klingt zwar etwas komisch, allerdings würde ich gerne einer Template-Funktion übergeben, welche Funktion aufgerufen werden soll. Diese soll bereits zur Compiletime ausgewertet werden.</p>
<p>Also schematisch etwa so:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
void call(const T&amp; t, &lt;functionName&gt;){
	t.&lt;functionName&gt;();
}
</code></pre>
<p>Der Code soll nur verdeutlichen, was ich eigentlich möchte und kann natürlich nicht ansatzweise so funktionieren.</p>
<p>Zur Zeit verwende ich zur Verwirklichung dieses Problems<br />
folgenden Ansatz (hier auch mit zusätzlichen Parametern für den Funktionsaufruf):</p>
<pre><code class="language-cpp">#include &lt;iostream&gt; 

struct Foo{
	void foo(int i) const{
		std::cout &lt;&lt; &quot;Foo::foo int&quot; &lt;&lt; std::endl;
	}
	void foo(double i) const{
		std::cout &lt;&lt; &quot;Foo::foo double&quot; &lt;&lt; std::endl;
	}
	void foo(int i, int j) const{
		std::cout &lt;&lt; &quot;Foo::foo 2*int&quot; &lt;&lt; std::endl;
	}
	void bar() const{
		std::cout &lt;&lt; &quot;Foo::bar&quot; &lt;&lt; std::endl;
	}
};

struct Bar{
	void foo(int i) const{
		std::cout &lt;&lt; &quot;Bar::foo int&quot; &lt;&lt; std::endl;
	}
	void foo(double d) const{
		std::cout &lt;&lt; &quot;Bar::foo double&quot; &lt;&lt; std::endl;
	}
	void bar() const{
		std::cout &lt;&lt; &quot;Bar::bar&quot; &lt;&lt; std::endl;
	}
};

template&lt;typename T&gt;
struct CallFoo{
	template&lt;typename... P&gt;
	static void call(const T&amp; t, P&amp;&amp;... p){
		t.foo(std::forward&lt;P&gt;(p)...);
	}
};

template&lt;typename T&gt;
struct CallBar{
	static void call(const T&amp; t){
		t.bar();
	}
};

template&lt;template&lt;typename&gt; class Func, typename T, typename... P&gt; void call(const T&amp; t, P&amp;&amp;... p){
	Func&lt;T&gt;::call(t, std::forward&lt;P&gt;(p)...);
}

int main(){ 
	Foo foo;
	Bar bar;
	call&lt;CallFoo&gt;(foo, 1);
	call&lt;CallFoo&gt;(foo, 1.0);
	call&lt;CallFoo&gt;(foo, 1, 1);
	call&lt;CallBar&gt;(foo);
	call&lt;CallFoo&gt;(bar, 1);
	call&lt;CallFoo&gt;(bar, 1.0);
	call&lt;CallBar&gt;(bar);
}
</code></pre>
<p>Hier sieht man auch, dass einfache Funktionszeiger nicht mehr ausreichen...</p>
<p>Geht es evtl. eleganter oder habt ihr Alternativvorschläge?</p>
<p>Gruß,<br />
XSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2200641</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2200641</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Tue, 10 Apr 2012 23:59:52 GMT</pubDate></item><item><title><![CDATA[Reply to Metaprogrammierung: Function-Pointer @Compiletime on Wed, 11 Apr 2012 00:10:10 GMT]]></title><description><![CDATA[<p>Ich kann an dem Beispiel nicht erkennen, was du eigentlich erreichen möchtest.</p>
<p>XSpille schrieb:</p>
<blockquote>
<p>der Titel klingt zwar etwas komisch, allerdings würde ich gerne einer Template-Funktion übergeben, welche Funktion aufgerufen werden soll. Diese soll bereits zur Compiletime ausgewertet werden.</p>
<p>Also schematisch etwa so:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
void call(const T&amp; t, &lt;functionName&gt;){
	t.&lt;functionName&gt;();
}
</code></pre>
</blockquote>
<p>Meinst du vielleicht so etwas?</p>
<pre><code class="language-cpp">template&lt;typename T, typename F&gt;
void call(const T&amp; t, const F&amp; function){
	function(t);
}

struct Type
{
	void method() const;
};

Type object;
call(object, std::bind(&amp;Type::method, _1));
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2200643</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2200643</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Wed, 11 Apr 2012 00:10:10 GMT</pubDate></item><item><title><![CDATA[Reply to Metaprogrammierung: Function-Pointer @Compiletime on Wed, 11 Apr 2012 00:13:15 GMT]]></title><description><![CDATA[<p>XSpille schrieb:</p>
<blockquote>
<p>Diese soll bereits zur Compiletime ausgewertet werden.</p>
</blockquote>
<p>Die Funktion? Das geht nicht. Du kannst den Compiler so nicht zwingen, etwas zur Compilezeit auszuwerten, was kein konstanter Ausdruck ist. Dafür gibt es allerdings constexpr.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2200645</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2200645</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Wed, 11 Apr 2012 00:13:15 GMT</pubDate></item><item><title><![CDATA[Reply to Metaprogrammierung: Function-Pointer @Compiletime on Wed, 11 Apr 2012 00:28:10 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/22298">@TyRoXx</a>: Okay... Dann hol ich mal etwas weiter aus...<br />
Ich möchte im Endeffekt eine Funktion haben</p>
<pre><code class="language-cpp">template&lt;typename...T, typename... P&gt;
void call(std::tuple&lt;T...&gt; tuple, std::tuple&lt;P...&gt; parameter, &lt;funcName&gt;);
</code></pre>
<p>die folgende Funktionen aufruft:</p>
<pre><code class="language-cpp">std::get&lt;0&gt;(tuple).&lt;funcName&gt;(std::get&lt;0&gt;(parameter));
// ...
std::get&lt;n&gt;(tuple).&lt;funcName&gt;(std::get&lt;n&gt;(parameter));
</code></pre>
<p>Dabei reicht mir ein std::bind (denke ich) nicht aus,<br />
da ich es auf unterschiedlichen Objekt-Typen mit unterschiedlichen Parameter-Typen ausführe.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/25760">@cooky451</a>: Das war natürlich falsch ausgedrückt. Ich wollte sagen, dass die Funktionsauswahl - foo(int) oder foo(double) - schon zur Compilezeit aufgewertet werden soll.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2200646</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2200646</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Wed, 11 Apr 2012 00:28:10 GMT</pubDate></item><item><title><![CDATA[Reply to Metaprogrammierung: Function-Pointer @Compiletime on Wed, 11 Apr 2012 00:40:10 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">template&lt;typename...T, typename... P, typename F&gt;
void call(std::tuple&lt;T...&gt; tuple, std::tuple&lt;P...&gt; parameter, const F &amp;function)
{
	function(
		std::get&lt;0&gt;(tuple),
		std::get&lt;0&gt;(parameter));
	// ...
}

struct func_abc
{
	template &lt;class T, class P&gt;
	void operator ()(const T &amp;t, const P &amp;p)
	{
		t.abc(p);
	}
};

call(.., .., func_abc());
</code></pre>
<p>Also ungefähr das?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2200648</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2200648</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Wed, 11 Apr 2012 00:40:10 GMT</pubDate></item><item><title><![CDATA[Reply to Metaprogrammierung: Function-Pointer @Compiletime on Wed, 11 Apr 2012 06:48:58 GMT]]></title><description><![CDATA[<p>Genau...</p>
<p>DANKE TyRoXx!</p>
<p>Gefällt mir wesentlich besser als mein Vorschlag.</p>
<p>Gruß,<br />
XSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2200667</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2200667</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Wed, 11 Apr 2012 06:48:58 GMT</pubDate></item><item><title><![CDATA[Reply to Metaprogrammierung: Function-Pointer @Compiletime on Wed, 11 Apr 2012 07:27:43 GMT]]></title><description><![CDATA[<p>Sieht mir nach einer natürlichen Anwengung für boost::fusion aus. Schau mal, ob da nicht bereits implementiert ist, was du brauchst</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2200671</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2200671</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Wed, 11 Apr 2012 07:27:43 GMT</pubDate></item><item><title><![CDATA[Reply to Metaprogrammierung: Function-Pointer @Compiletime on Wed, 11 Apr 2012 07:32:11 GMT]]></title><description><![CDATA[<p>XSpille schrieb:</p>
<blockquote>
<pre><code class="language-cpp">std::get&lt;0&gt;(tuple).&lt;funcName&gt;(std::get&lt;0&gt;(parameter));
// ...
std::get&lt;n&gt;(tuple).&lt;funcName&gt;(std::get&lt;n&gt;(parameter));
</code></pre>
</blockquote>
<p>Das geht nur, wenn die Elemente beider tupels vom gleichen Typ sind, weil sonst &lt;funcName&gt; zwar immer der gleiche Name, aber immer eine völlig andere Funktion ist.</p>
<p>Falls es so ist, machen tupel eigentlich keinen Sinn, sondern eher std::array oder sowas.</p>
<p>Falls es nicht so ist, müsstest du ein template für jeden Funktionsnamen bereitstellen, etwa wie folgt:</p>
<pre><code class="language-cpp">template &lt;class T, class P&gt;
struct callMemFoo
{
  void operator()(T&amp; t, P&amp; p)
  { t.foo(p); }
};

template &lt; template&lt;class, class&gt; class F, typename... T, typename... P&gt;
void call(std::tuple&lt;T...&gt; ts, std::tuple&lt;P...&gt; ps);
</code></pre>
<p>Implementiert sähe die call-Funktion dann so aus:</p>
<pre><code class="language-cpp">#include &lt;tuple&gt;

template &lt;typename T, typename P, template&lt;class, class&gt; class F, unsigned N&gt;
struct do_call
{
  void operator()(T&amp; t, P&amp; p)
  {
    const static unsigned Pos = std::tuple_size&lt;T&gt;::value - N;
    auto f = F&lt;typename std::tuple_element&lt;Pos,T&gt;::type, 
      typename std::tuple_element&lt;Pos,P&gt;::type&gt;();
    f(std::get&lt;Pos&gt;(t), std::get&lt;Pos&gt;(p));

    do_call&lt;T, P, F, N-1&gt; call_next;
    call_next(t, p);
  }
};

template &lt;typename T, typename P, template&lt;class, class&gt; class F&gt;
struct do_call&lt;T, P, F, 0&gt;
{
  void operator()(T&amp;, P&amp;){}
};

template &lt; template&lt;class, class&gt; class F, typename... T, typename... P&gt;
void call(std::tuple&lt;T...&gt; ts, std::tuple&lt;P...&gt; ps)
{
  static_assert(sizeof...(T) == sizeof...(P), &quot;T and P tuples must have same size&quot;); 

  do_call&lt;std::tuple&lt;T...&gt;, std::tuple&lt;P...&gt;, F, sizeof...(T)&gt; call_first;
  call_first(ts, ps); 
}
</code></pre>
<p>Läuft unter GCC, Beispiel: <a href="http://ideone.com/WBPjk" rel="nofollow">http://ideone.com/WBPjk</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2200672</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2200672</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Wed, 11 Apr 2012 07:32:11 GMT</pubDate></item><item><title><![CDATA[Reply to Metaprogrammierung: Function-Pointer @Compiletime on Wed, 11 Apr 2012 12:10:32 GMT]]></title><description><![CDATA[<p>Danke otze, werde ich mir heute abend in Ruhe mal angucken.</p>
<p>Danke pumuckl, wie ich es ansonsten verwirkliche ist mir klar.<br />
Ich erstelle mir Indizes, dann kann ich auch Rückgabewerte einfach wieder in ein Tupel packen.</p>
<p>Es sollen unterschiedliche Typen sein, die gewisse Funktionen haben (somit unterschiedliche Funktionen).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2200767</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2200767</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Wed, 11 Apr 2012 12:10:32 GMT</pubDate></item></channel></rss>