<?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[Iterative Templates, partielle Spezialisierung]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich feile gerade an meiner Bachelorarbeit und habe ein Problem (mal wieder) mit Templates. Es geht um eine &quot;raised cosine&quot; Reihe, die ich mit Templates darstellen möchte. Keine Angst es wird nicht mathematisch, weil es nur um den Code geht.</p>
<p>Die Reihe, die ich brauche ist definiert als:</p>
<pre><code>rcos[t]n[/t](w) = rcos[t]n-1[/t](w) + (-1)[h]n[/h] * a[t]n[/t] * cos(w*n)
rcos[t]0[/t](w) = a[t]0[/t]
</code></pre>
<p>Mit anderen Worten ist sie eben iterativ und eine Summe aus n+1 Termen wobei jeder Term a<sub>n</sub>*cos(w*n) ist mit abwechselndem Vorzeichen. Der Code sollte sehr performant ablaufen, deshalb wäre es für kleine n schön, die Funktion inline zu haben.</p>
<p>Da ich mich mit Fließkommagenauigkeiten noch nicht beschäftigen möchte ist ohnehin alles mit Templates gelöst worden, sodass ich floats oder doubles nehmen kann. Das Problem für den Compiler entsteht in den Zeilen mit den vielen Ausrufezeichen (C2768). Ich kann mit dem Fehler etwas anfangen, aber ich weiß nicht, wie ich ihn beheben kann. Ich möchte ein Template soweit spezialisieren, dass ein Templateparameter explizit ist und der andere weiterhin dynamisch bleibt, siehe Code unterhalb.</p>
<p>Ich würde mich sehr über Hilfe freuen, damit ich nicht bei der Implementierung weiterer Reihe abklopfen muss. Vielen Dank!</p>
<pre><code class="language-cpp">// anyheader.h
template&lt;unsigned int Order, typename Precision&gt;
inline Precision raised_cosine(const Precision w,
	const Precision *a
)
{
	return raised_cosine&lt;Order-1, Precision&gt;(w, a)
		+ a[Order]*cos(w * Order)*((Order&amp;0x1)?-1:1);
}

template&lt;unsigned int Order, typename Precision&gt;
inline Precision raised_cosine(const Precision w,
	const Precision (&amp;a)[Order]
)
{
	return raised_cosine&lt;Order, Precision&gt;(w, (const Precision *)&amp;a);
}

// C2768 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
template&lt;typename Precision&gt;
inline Precision raised_cosine&lt;0, Precision&gt;(const Precision w,
	const Precision *a
)
{
	return a[0];
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

// ----------------------------------------
// Blackman-Harris window
// ----------------------------------------
#define BLACKMANHARRIS_A0 0.35875
#define BLACKMANHARRIS_A1 0.48829
#define BLACKMANHARRIS_A2 0.14128
#define BLACKMANHARRIS_A3 0.01168
// ----------------------------------------
template&lt;typename Precision&gt;
Precision window_blackmanharris(Precision n, Precision N)
{
	const Precision w = n/(N-1) * 2 * M_PI;

	/* old implementation
	return (Precision)BLACKMANHARRIS_A0
		- cos(factor    ) * BLACKMANHARRIS_A1
		+ cos(factor * 2) * BLACKMANHARRIS_A2 
		- cos(factor * 3) * BLACKMANHARRIS_A3;
		*/

	const Precision a[] =
		{ BLACKMANHARRIS_A0, BLACKMANHARRIS_A1,
		BLACKMANHARRIS_A2, BLACKMANHARRIS_A3};

	return raised_cosine&lt;4, Precision&gt;(w, a); // explicit templates
}
// ----------------------------------------

// main.cpp
int main()
{
	std::cout &lt;&lt; window_blackmanharris&lt;float&gt;( 3.f, 10.f) &lt;&lt; std::endl; // edit cout
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/298036/iterative-templates-partielle-spezialisierung</link><generator>RSS for Node</generator><lastBuildDate>Fri, 14 Aug 2026 03:14:35 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/298036.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 12 Jan 2012 12:18:23 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Iterative Templates, partielle Spezialisierung on Thu, 12 Jan 2012 12:45:24 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich feile gerade an meiner Bachelorarbeit und habe ein Problem (mal wieder) mit Templates. Es geht um eine &quot;raised cosine&quot; Reihe, die ich mit Templates darstellen möchte. Keine Angst es wird nicht mathematisch, weil es nur um den Code geht.</p>
<p>Die Reihe, die ich brauche ist definiert als:</p>
<pre><code>rcos[t]n[/t](w) = rcos[t]n-1[/t](w) + (-1)[h]n[/h] * a[t]n[/t] * cos(w*n)
rcos[t]0[/t](w) = a[t]0[/t]
</code></pre>
<p>Mit anderen Worten ist sie eben iterativ und eine Summe aus n+1 Termen wobei jeder Term a<sub>n</sub>*cos(w*n) ist mit abwechselndem Vorzeichen. Der Code sollte sehr performant ablaufen, deshalb wäre es für kleine n schön, die Funktion inline zu haben.</p>
<p>Da ich mich mit Fließkommagenauigkeiten noch nicht beschäftigen möchte ist ohnehin alles mit Templates gelöst worden, sodass ich floats oder doubles nehmen kann. Das Problem für den Compiler entsteht in den Zeilen mit den vielen Ausrufezeichen (C2768). Ich kann mit dem Fehler etwas anfangen, aber ich weiß nicht, wie ich ihn beheben kann. Ich möchte ein Template soweit spezialisieren, dass ein Templateparameter explizit ist und der andere weiterhin dynamisch bleibt, siehe Code unterhalb.</p>
<p>Ich würde mich sehr über Hilfe freuen, damit ich nicht bei der Implementierung weiterer Reihe abklopfen muss. Vielen Dank!</p>
<pre><code class="language-cpp">// anyheader.h
template&lt;unsigned int Order, typename Precision&gt;
inline Precision raised_cosine(const Precision w,
	const Precision *a
)
{
	return raised_cosine&lt;Order-1, Precision&gt;(w, a)
		+ a[Order]*cos(w * Order)*((Order&amp;0x1)?-1:1);
}

template&lt;unsigned int Order, typename Precision&gt;
inline Precision raised_cosine(const Precision w,
	const Precision (&amp;a)[Order]
)
{
	return raised_cosine&lt;Order, Precision&gt;(w, (const Precision *)&amp;a);
}

// C2768 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
template&lt;typename Precision&gt;
inline Precision raised_cosine&lt;0, Precision&gt;(const Precision w,
	const Precision *a
)
{
	return a[0];
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

// ----------------------------------------
// Blackman-Harris window
// ----------------------------------------
#define BLACKMANHARRIS_A0 0.35875
#define BLACKMANHARRIS_A1 0.48829
#define BLACKMANHARRIS_A2 0.14128
#define BLACKMANHARRIS_A3 0.01168
// ----------------------------------------
template&lt;typename Precision&gt;
Precision window_blackmanharris(Precision n, Precision N)
{
	const Precision w = n/(N-1) * 2 * M_PI;

	/* old implementation
	return (Precision)BLACKMANHARRIS_A0
		- cos(factor    ) * BLACKMANHARRIS_A1
		+ cos(factor * 2) * BLACKMANHARRIS_A2 
		- cos(factor * 3) * BLACKMANHARRIS_A3;
		*/

	const Precision a[] =
		{ BLACKMANHARRIS_A0, BLACKMANHARRIS_A1,
		BLACKMANHARRIS_A2, BLACKMANHARRIS_A3};

	return raised_cosine&lt;4, Precision&gt;(w, a); // explicit templates
}
// ----------------------------------------

// main.cpp
int main()
{
	std::cout &lt;&lt; window_blackmanharris&lt;float&gt;( 3.f, 10.f) &lt;&lt; std::endl; // edit cout
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2167125</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2167125</guid><dc:creator><![CDATA[PhilippHToner]]></dc:creator><pubDate>Thu, 12 Jan 2012 12:45:24 GMT</pubDate></item><item><title><![CDATA[Reply to Iterative Templates, partielle Spezialisierung on Thu, 12 Jan 2012 12:30:44 GMT]]></title><description><![CDATA[<p>1.- erstmal wäre es schön zu wissen welchen compiler du benutzt, ich tippe auf MSVC...<br />
sonst könnte die fehlermeldung sonstwas sein.</p>
<p>2.- an deiner stelle, nur um den überblick zu wahren, schreib die template argumente bei den aufrufen hin<br />
-&gt;</p>
<pre><code class="language-cpp">int main()
{
    cout &lt;&lt; window_blackmanharris&lt;float&gt;(3.0f, 10.0f) &lt;&lt; endl;
    return 0x0;
}
</code></pre>
<p>3.- wenn du schon solche reinen C++ dinge wie templates nutzt, nutz wenigstens auch den rest an c++, sprich in dem fall cout</p>
<p>4.- und die fehlermeldung (jedenfalls die von msvc) besagt, dass der compiler sich die richtige funktion nicht selbst herleiten kann, ich denke, wenn du die template argumente angibst wird der fehler weg sein</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2167127</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2167127</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Thu, 12 Jan 2012 12:30:44 GMT</pubDate></item><item><title><![CDATA[Reply to Iterative Templates, partielle Spezialisierung on Thu, 12 Jan 2012 12:37:05 GMT]]></title><description><![CDATA[<p>Verwechselst du da gerade iterativ und rekursiv? Wie auch immer: <a href="http://stackoverflow.com/questions/1416345/c-template-specialization" rel="nofollow">http://stackoverflow.com/questions/1416345/c-template-specialization</a></p>
<p>Skym0sh0 schrieb:</p>
<blockquote>
<p>4.- und die fehlermeldung (jedenfalls die von msvc) besagt, dass der compiler sich die richtige funktion nicht selbst herleiten kann, ich denke, wenn du die template argumente angibst wird der fehler weg sein</p>
</blockquote>
<p>Eher nicht. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2167128</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2167128</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Thu, 12 Jan 2012 12:37:05 GMT</pubDate></item><item><title><![CDATA[Reply to Iterative Templates, partielle Spezialisierung on Thu, 12 Jan 2012 12:55:54 GMT]]></title><description><![CDATA[<p>Ja ich benutze MSVC++.</p>
<p>Habe den Code angepasst, sodass alle Funktionen explizit aufgerufen werden, aber es bleibt nach wie vor der Fehler.<br />
Den Link habe ich mir ebenfalls angeschaut und soweit verstanden &quot;Funktionstemplates lassen sich nicht partiell spezialisieren, nur vollständig und dann werden diese überladen&quot;. Die Frage ist nur, warum es so ist. Mein Code ist doch nicht zweideutig?</p>
<p>Wenn sich die Funktionen gegenseitig überladen, dann wären reine Builtins (template&lt;int i&gt;) für Funktionen ja immer Schwachsinn, weil die Signatur(Name + Parametertypen + const/nicht-const) der Methode sich nicht ändert und wenn ich raised_cosine&lt;100&gt; Aufrufe wird die Funktion 100x überschrieben, aber es wird immer nur die letzte überschriebene Funktion aufgerufen, also raised_cosine&lt;0&gt;? Stimmt das so?</p>
<p>Danke für die Antworten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2167134</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2167134</guid><dc:creator><![CDATA[PhilippHToner]]></dc:creator><pubDate>Thu, 12 Jan 2012 12:55:54 GMT</pubDate></item><item><title><![CDATA[Reply to Iterative Templates, partielle Spezialisierung on Thu, 12 Jan 2012 13:18:12 GMT]]></title><description><![CDATA[<p>Ich würde mich weiterhin auf Antworten freuen, aber erstmal hat sich das Thema erledigt. Ich habe die Implementierung geändert und es kompiliert. Trotzdem stimmt die Ausgabe nicht, aber das ist ein mathematischer Fehler. Danke nochmal! Hier der neue Code:</p>
<p>edit (+code): jetzt scheint die Ausgabe zu stimmen n=0 muss gesondert behandelt werden.</p>
<pre><code class="language-cpp">template&lt;typename Precision&gt;
inline Precision raised_cosine(size_t order, const Precision w,
	const Precision *a
)
{
	Precision value = (Precision)0;

	// edited
	while(order--&gt;0)
		value += a[order]*cos(w * order)*((order&amp;0x1)?-1:1);

	return value + a[0];
}

// Aufruf mit festem Array nimmt Arbeit ab
template&lt;size_t Order, typename Precision&gt;
inline Precision raised_cosine(const Precision w,
	const Precision (&amp;a)[Order]
)
{
	return raised_cosine&lt;Precision&gt;(Order, w, (const Precision *)&amp;a);
}

// ----------------------------------------
// Blackman-Harris window
// ----------------------------------------
#define BLACKMANHARRIS_A0 0.35875
#define BLACKMANHARRIS_A1 0.48829
#define BLACKMANHARRIS_A2 0.14128
#define BLACKMANHARRIS_A3 0.01168
// ----------------------------------------
template&lt;typename Precision&gt;
Precision window_blackmanharris(Precision n, Precision N)
{
	const Precision w = n/(N-1) * (Precision)2 * (Precision)M_PI;

	/*
	return (Precision)BLACKMANHARRIS_A0
		- cos(factor    ) * BLACKMANHARRIS_A1
		+ cos(factor * 2) * BLACKMANHARRIS_A2 
		- cos(factor * 3) * BLACKMANHARRIS_A3;
		*/

	const Precision a[] = {
		(Precision)BLACKMANHARRIS_A0,
		(Precision)BLACKMANHARRIS_A1,
		(Precision)BLACKMANHARRIS_A2,
		(Precision)BLACKMANHARRIS_A3};

	return raised_cosine(w, a);
}
// ----------------------------------------

int main()
{
	std::cout &lt;&lt; window_blackmanharris&lt;float&gt;( 3.f, 10.f) &lt;&lt; std::endl;
	std::cin.get();

}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2167145</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2167145</guid><dc:creator><![CDATA[PhilippHToner]]></dc:creator><pubDate>Thu, 12 Jan 2012 13:18:12 GMT</pubDate></item><item><title><![CDATA[Reply to Iterative Templates, partielle Spezialisierung on Thu, 12 Jan 2012 19:15:02 GMT]]></title><description><![CDATA[<p>Hallo PhilippHToner,</p>
<p>Willkommen im C++-Forum.</p>
<p>Dass sich Funktionstemplates nicht spezialisieren lassen, hast Du ja schon bemerkt. Nun - dann benutze keine Funktionen, sondern Strukturen und diese darfst Du partiell spezialisieren, wobei das hier gar nicht notwendig ist. Und weil eine Funktion benötigt wird, baue man sich eine statische Methode bei eben vorher erwähnter Struktur.</p>
<pre><code class="language-cpp">#include &lt;cmath&gt; // std::cos, u.a.
#include &lt;iostream&gt;

namespace
{
    const double PI = std::acos(-1.0);

    namespace blackman_harris
    {
        // siehe &lt;http://de.wikipedia.org/wiki/Fensterfunktion#Blackman-Harris_Fenster&gt;
        const double a[] = { 0.35875, 0.48829, 0.14128, 0.01168 };
    }
}

template&lt; int N &gt;
struct raised_cosine;

template&lt; int N &gt;
struct raised_cosine&lt; N &gt;
{
    static double calc( double n )
    {
        static_assert( N &lt; sizeof(blackman_harris::a)/sizeof(*blackman_harris::a), &quot;blackman_harris::a[N] fuer dieses N nicht verfuegbar&quot; );
        static_assert( N &gt; 1, &quot;raised_cosine&lt; N &gt; erst ab N&gt;1 definiert&quot; );
        return calc_( 2*PI*n/(N-1) );
    }

    static double calc_( double w )
    {
        return raised_cosine&lt; N-1 &gt;::calc_( w ) + sgn( blackman_harris::a[N] ) * std::cos( w*N );
    }
    static double sgn( double a )
    {
        return -raised_cosine&lt; N-1 &gt;::sgn( a );
    }
};

template&lt;&gt;
struct raised_cosine&lt; 0 &gt;
{
    static double calc_( double /*w*/ )
    {
        return blackman_harris::a[0];
    }
    static double sgn( double a )
    {
        return a;
    }
};

int main()
{
    using namespace std;
    for( double x; cin &gt;&gt; x; )
        cout &lt;&lt; &quot;raised_cosine(&quot; &lt;&lt; x &lt;&lt; &quot;) = &quot; &lt;&lt; raised_cosine&lt; 3 &gt;::calc( x ) &lt;&lt; endl;
    return 0;
}
</code></pre>
<p>Wenn man sich das ganze im Maschinencode anschaut, dann wird alles als ein Ausdruck ohne Schleife und ohne Unterprogramm-Aufruf übersetzt. Schneller ist es kaum zu machen. Zumal dort auch keine Multiplikation mit 1 oder -1 mehr passiert, so wie in Deinem Code.</p>
<p>Auf die defines in Deinem Code würde ich verzichten. Ein sprechender namespace ist hier die erste Wahl (s.Code).</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2167344</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2167344</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Thu, 12 Jan 2012 19:15:02 GMT</pubDate></item><item><title><![CDATA[Reply to Iterative Templates, partielle Spezialisierung on Thu, 12 Jan 2012 20:37:45 GMT]]></title><description><![CDATA[<p>Hallo Werner,</p>
<p>coole Lösung, die auf jeden Fall schöner ist. Namespaces sind schön, das stimmt, aber in deiner Lösung hat man nicht die Möglichkeit anderen a-Parameter zu verwenden, weil man namespaces nicht als Parameter übergeben kann. Es gibt ja noch mehrere raised_cosine Fenster, die ich einbauen will.</p>
<p>Ich könnte mir vorstellen noch einen &quot;typename Coefs&quot; als Parameter zu übergeben und auf die Koeffizienten über Coefs::a zugreifen, würde das gehen? Ich probier das morgen einmal aus.</p>
<p>Danke nochmal.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2167381</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2167381</guid><dc:creator><![CDATA[PhilippHToner]]></dc:creator><pubDate>Thu, 12 Jan 2012 20:37:45 GMT</pubDate></item><item><title><![CDATA[Reply to Iterative Templates, partielle Spezialisierung on Thu, 12 Jan 2012 20:45:57 GMT]]></title><description><![CDATA[<p>PhilippHToner schrieb:</p>
<blockquote>
<p>... in deiner Lösung hat man nicht die Möglichkeit anderen a-Parameter zu verwenden, weil man namespaces nicht als Parameter übergeben kann. Es gibt ja noch mehrere raised_cosine Fenster, die ich einbauen will.</p>
</blockquote>
<p>Ich hatte nicht registriert, dass dies eine Anforderung ist. Aber das lässt sich doch leicht nachrüsten. Wenn Du da noch Fragen hast, so melde Dich einfach nochmal.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2167387</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2167387</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Thu, 12 Jan 2012 20:45:57 GMT</pubDate></item></channel></rss>