<?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[Objekt-Typ abhängig von Eigenschaften eines Types (Template)]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich progge gerade ein (template-basiertes) neuronales Netz, das in (drei) verschiedenen Schichten unterschiedliche Neuronen hat. Je nachdem welche Neuronen verwendet werden haben diese Parameter von unterschiedlichen Typen oder nicht. Diese Parameter möchte ich nun auslesen um sie per EA zu modifizieren und zurückschreiben.</p>
<p>Also nun zu meinem daraus abgeleiteten relativ abstrakten Problem:<br />
Ich habe eine Struktur mit zwei Listen von verschiedenen Typen. Aus dieser Struktur möchte ich die Parameter auslesen. Die zurückgelieferte Struktur ist natürlich abhängig von Typen darin und enthält jeweils separate Listen für Parameterinformationen für Typ T1 und Typ T2. Wenn allerdings einer der Typen keine Parameterinformationen hat, möchte ich ungern eine Liste mit einem Dummy-Typen haben. Deswegen habe ich mir überlegt wie ich es am besten lösen kann. Für den Fall, dass ein Typ Parameter hat, brauche ich eine Liste, ansonsten (optimalerweise gar nichts oder) ein leeres Parameterinfo Objekt. Zuerst muss ich dazu mein Objekt irgendwie kennzeichnen, ob er Parameter hat. Da diese Information zur Kompilierzeit gebraucht wird, muss es eine Konstante sein. Anhand dieser Konstante soll nun zur Kompilierzeit entschieden werden, ob ein Objekt mit Parameterinformationen oder ohne benötigt wird. Dazu habe ich eine Template-Spezialisierung für den Fall geschrieben, falls ein übergebener Template-Parameter gleich false ist. Damit man diesen 'Schummel'-Parameter nach außen nicht sieht, habe ich davon abeleitet. Dieser Parameter wird mit Hilfe der Konstanten gesetzt. Somit brauch ich nur ein Objekt mit dem entsprechenden Typ als Parameter erstellen und ich habe (nur) alle notwendigen Infos. Ähnlich bin ich auch bei den Funktionen für das füllen dieser Objekte vorgegangen. Da man keine partiellen Spezialisierungen für Template-Funktionen erstellen kann, greife ich auch hier auf eine Klasse zurück, die nichts macht falls der Template-Parameter false ist, ansonsten die Daten überträgt.</p>
<p>Hier der Code dazu (Sorry, dass er so lang ist):</p>
<pre><code class="language-cpp">#include &lt;vector&gt;
#include &lt;utility&gt;
#include &lt;iostream&gt;

class Foo{
public:
	static const bool has_parameters = false; 
};

template&lt;typename T&gt;
class Bar{
public:
	typedef T parameter_type;
	Bar(parameter_type i) : _param(i){}
	static const bool has_parameters = true; 
	parameter_type param() const{ return _param;}
private:
	parameter_type _param;
};

template&lt;typename T, bool b&gt;
class ParameterListBase{};

template&lt;typename T&gt;
class ParameterListBase&lt;T, true&gt;{
public:
	std::vector&lt;typename T::parameter_type&gt; vector;
};

template&lt;typename T&gt;
class ParameterListBase&lt;T, false&gt;{};

template&lt;typename T&gt;
class ParameterList : public ParameterListBase&lt;T, T::has_parameters&gt;{};

template&lt;typename T1, typename T2&gt;
struct FooBar{
	ParameterList&lt;T1&gt; first;
	ParameterList&lt;T2&gt; second;
};

template&lt;bool b&gt;
class ParameterExtractor{};

template&lt;&gt;
class ParameterExtractor&lt;true&gt;{
public:
template&lt;typename T&gt;
void operator()(std::vector&lt;T&gt;&amp; vec, ParameterList&lt;T&gt;&amp; list){
	for(T&amp; t : vec){
		list.vector.push_back(t.param());
		std::cout &lt;&lt; t.param() &lt;&lt; &quot; &quot;;
	}
	std::cout &lt;&lt; std::endl;
}
};

template&lt;&gt;
class ParameterExtractor&lt;false&gt;{
public:
template&lt;typename T&gt;
void operator()(std::vector&lt;T&gt;&amp; , ParameterList&lt;T&gt;&amp;){
	std::cout &lt;&lt; &quot;no param info&quot; &lt;&lt; std::endl;
}
};

template&lt;typename T1, typename T2&gt;
FooBar&lt;T1, T2&gt; extract_params(std::pair&lt;std::vector&lt;T1&gt;, std::vector&lt;T2&gt; &gt; data){
	FooBar&lt;T1,T2&gt; foobar;
	ParameterExtractor&lt;T1::has_parameters&gt; extractor1;
	extractor1(data.first, foobar.first);
	ParameterExtractor&lt;T2::has_parameters&gt; extractor2;
	extractor2(data.second, foobar.second);
	return foobar;
}

int main(){
	std::vector&lt;Foo&gt; foos;
	std::vector&lt;Bar&lt;int&gt; &gt; bars1;
	std::vector&lt;Bar&lt;float&gt; &gt; bars2;
	foos.push_back(Foo());
	bars1.push_back(Bar&lt;int&gt;(1));
	bars1.push_back(Bar&lt;int&gt;(2));
	bars2.push_back(Bar&lt;float&gt;(0.815));
	extract_params(std::make_pair(bars1, foos));
	std::cout &lt;&lt; &quot;---&quot; &lt;&lt; std::endl;
	extract_params(std::make_pair(bars2, bars1));
}
</code></pre>
<p>Also der Code funktioniert auch genauso wie er soll.</p>
<blockquote>
<p>1 2<br />
no param info<br />
---<br />
0.815<br />
1 2</p>
</blockquote>
<p>Irgendwie kommt mir mein Vorgehen etwas komisch vor. Würdet ihr so etwas analog lösen?<br />
Was würdet ihr anders machen?<br />
Gibt es eine Möglichkeit die entsprechenden Felder in FooBar nur zu erzeugen, wenn der Typ Paramter hat? Also ich erzeuge sonst ja leere Objekte.</p>
<p>Gruß,<br />
XSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/284775/objekt-typ-abhängig-von-eigenschaften-eines-types-template</link><generator>RSS for Node</generator><lastBuildDate>Fri, 21 Aug 2026 20:09:11 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/284775.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 07 Apr 2011 18:12:36 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Objekt-Typ abhängig von Eigenschaften eines Types (Template) on Thu, 07 Apr 2011 18:12:36 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich progge gerade ein (template-basiertes) neuronales Netz, das in (drei) verschiedenen Schichten unterschiedliche Neuronen hat. Je nachdem welche Neuronen verwendet werden haben diese Parameter von unterschiedlichen Typen oder nicht. Diese Parameter möchte ich nun auslesen um sie per EA zu modifizieren und zurückschreiben.</p>
<p>Also nun zu meinem daraus abgeleiteten relativ abstrakten Problem:<br />
Ich habe eine Struktur mit zwei Listen von verschiedenen Typen. Aus dieser Struktur möchte ich die Parameter auslesen. Die zurückgelieferte Struktur ist natürlich abhängig von Typen darin und enthält jeweils separate Listen für Parameterinformationen für Typ T1 und Typ T2. Wenn allerdings einer der Typen keine Parameterinformationen hat, möchte ich ungern eine Liste mit einem Dummy-Typen haben. Deswegen habe ich mir überlegt wie ich es am besten lösen kann. Für den Fall, dass ein Typ Parameter hat, brauche ich eine Liste, ansonsten (optimalerweise gar nichts oder) ein leeres Parameterinfo Objekt. Zuerst muss ich dazu mein Objekt irgendwie kennzeichnen, ob er Parameter hat. Da diese Information zur Kompilierzeit gebraucht wird, muss es eine Konstante sein. Anhand dieser Konstante soll nun zur Kompilierzeit entschieden werden, ob ein Objekt mit Parameterinformationen oder ohne benötigt wird. Dazu habe ich eine Template-Spezialisierung für den Fall geschrieben, falls ein übergebener Template-Parameter gleich false ist. Damit man diesen 'Schummel'-Parameter nach außen nicht sieht, habe ich davon abeleitet. Dieser Parameter wird mit Hilfe der Konstanten gesetzt. Somit brauch ich nur ein Objekt mit dem entsprechenden Typ als Parameter erstellen und ich habe (nur) alle notwendigen Infos. Ähnlich bin ich auch bei den Funktionen für das füllen dieser Objekte vorgegangen. Da man keine partiellen Spezialisierungen für Template-Funktionen erstellen kann, greife ich auch hier auf eine Klasse zurück, die nichts macht falls der Template-Parameter false ist, ansonsten die Daten überträgt.</p>
<p>Hier der Code dazu (Sorry, dass er so lang ist):</p>
<pre><code class="language-cpp">#include &lt;vector&gt;
#include &lt;utility&gt;
#include &lt;iostream&gt;

class Foo{
public:
	static const bool has_parameters = false; 
};

template&lt;typename T&gt;
class Bar{
public:
	typedef T parameter_type;
	Bar(parameter_type i) : _param(i){}
	static const bool has_parameters = true; 
	parameter_type param() const{ return _param;}
private:
	parameter_type _param;
};

template&lt;typename T, bool b&gt;
class ParameterListBase{};

template&lt;typename T&gt;
class ParameterListBase&lt;T, true&gt;{
public:
	std::vector&lt;typename T::parameter_type&gt; vector;
};

template&lt;typename T&gt;
class ParameterListBase&lt;T, false&gt;{};

template&lt;typename T&gt;
class ParameterList : public ParameterListBase&lt;T, T::has_parameters&gt;{};

template&lt;typename T1, typename T2&gt;
struct FooBar{
	ParameterList&lt;T1&gt; first;
	ParameterList&lt;T2&gt; second;
};

template&lt;bool b&gt;
class ParameterExtractor{};

template&lt;&gt;
class ParameterExtractor&lt;true&gt;{
public:
template&lt;typename T&gt;
void operator()(std::vector&lt;T&gt;&amp; vec, ParameterList&lt;T&gt;&amp; list){
	for(T&amp; t : vec){
		list.vector.push_back(t.param());
		std::cout &lt;&lt; t.param() &lt;&lt; &quot; &quot;;
	}
	std::cout &lt;&lt; std::endl;
}
};

template&lt;&gt;
class ParameterExtractor&lt;false&gt;{
public:
template&lt;typename T&gt;
void operator()(std::vector&lt;T&gt;&amp; , ParameterList&lt;T&gt;&amp;){
	std::cout &lt;&lt; &quot;no param info&quot; &lt;&lt; std::endl;
}
};

template&lt;typename T1, typename T2&gt;
FooBar&lt;T1, T2&gt; extract_params(std::pair&lt;std::vector&lt;T1&gt;, std::vector&lt;T2&gt; &gt; data){
	FooBar&lt;T1,T2&gt; foobar;
	ParameterExtractor&lt;T1::has_parameters&gt; extractor1;
	extractor1(data.first, foobar.first);
	ParameterExtractor&lt;T2::has_parameters&gt; extractor2;
	extractor2(data.second, foobar.second);
	return foobar;
}

int main(){
	std::vector&lt;Foo&gt; foos;
	std::vector&lt;Bar&lt;int&gt; &gt; bars1;
	std::vector&lt;Bar&lt;float&gt; &gt; bars2;
	foos.push_back(Foo());
	bars1.push_back(Bar&lt;int&gt;(1));
	bars1.push_back(Bar&lt;int&gt;(2));
	bars2.push_back(Bar&lt;float&gt;(0.815));
	extract_params(std::make_pair(bars1, foos));
	std::cout &lt;&lt; &quot;---&quot; &lt;&lt; std::endl;
	extract_params(std::make_pair(bars2, bars1));
}
</code></pre>
<p>Also der Code funktioniert auch genauso wie er soll.</p>
<blockquote>
<p>1 2<br />
no param info<br />
---<br />
0.815<br />
1 2</p>
</blockquote>
<p>Irgendwie kommt mir mein Vorgehen etwas komisch vor. Würdet ihr so etwas analog lösen?<br />
Was würdet ihr anders machen?<br />
Gibt es eine Möglichkeit die entsprechenden Felder in FooBar nur zu erzeugen, wenn der Typ Paramter hat? Also ich erzeuge sonst ja leere Objekte.</p>
<p>Gruß,<br />
XSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2046134</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2046134</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Thu, 07 Apr 2011 18:12:36 GMT</pubDate></item><item><title><![CDATA[Reply to Objekt-Typ abhängig von Eigenschaften eines Types (Template) on Thu, 07 Apr 2011 18:31:25 GMT]]></title><description><![CDATA[<p>XSpille schrieb:</p>
<blockquote>
<p>Gibt es eine Möglichkeit die entsprechenden Felder in FooBar nur zu erzeugen, wenn der Typ Paramter hat?</p>
</blockquote>
<p>Gerade auf den Abschicken-Button gedrückt, da kam mir die Idee <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f4a1.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--light_bulb"
      title=":bulb:"
      alt="💡"
    /></p>
<p>Also so kann man es Lösen:</p>
<pre><code class="language-cpp">class Foo{
public:
        static const bool has_parameters = false;
};

template&lt;typename T&gt;
class Bar{
public:
        static const bool has_parameters = true;
        typedef T parameter_type;
};

template&lt;typename T, bool b&gt;
class AInfo{};

template&lt;typename T, bool b&gt;
class BInfo{};

template&lt;typename T, bool b&gt;
class CInfo{};

template&lt;typename T&gt;
class AInfo&lt;T, true&gt;{ public: typename T::parameter_type* a(){return 0;} };

template&lt;typename T&gt;
class BInfo&lt;T, true&gt;{ public: typename T::parameter_type* b(){return 0;} };

template&lt;typename T&gt;
class CInfo&lt;T, true&gt;{ public: typename T::parameter_type* c(){return 0;} };

template&lt;typename T1, typename T2, typename T3&gt;
class Info : public AInfo&lt;T1, T1::has_parameters&gt;, public BInfo&lt;T2, T2::has_parameters&gt;, public CInfo&lt;T3, T3::has_parameters&gt;{
};

int main(){
        Info&lt;Bar&lt;int&gt;, Foo, Bar&lt;float&gt; &gt; info;
        int* i = info.a();
        // info.b(); ### not available ###
        float* f = info.c();
}
</code></pre>
<p>EDIT: Ist natürlich schon eher Spielerei, aber manchmal will man halt wissen, ob man etwas verwirklichen kann</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2046140</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2046140</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Thu, 07 Apr 2011 18:31:25 GMT</pubDate></item><item><title><![CDATA[Reply to Objekt-Typ abhängig von Eigenschaften eines Types (Template) on Sun, 10 Apr 2011 08:54:24 GMT]]></title><description><![CDATA[<p>Hier (wegen der Vollständigkeit) ein anderer Ansatz um nach Bedarf der Template-Parameter member-Variablen zu erzeugen:</p>
<pre><code class="language-cpp">#include &lt;vector&gt;
#include &lt;iostream&gt;
#include &lt;boost/type_traits/add_reference.hpp&gt;

template&lt;typename T&gt;
class Foo{
public:
        typedef T parameter_type;
};
class Bar{
public:
        typedef void parameter_type;
};

template&lt;typename T,int I=0&gt;
class OptionalValue{
protected:
        T&amp; value(){ return t; }
        T t;
};

template&lt;int I&gt;
class OptionalValue&lt;void, I&gt;{
protected:
        void value(){}
};

template&lt;typename T1, typename T2&gt;
class FooBar : public OptionalValue&lt;typename T1::parameter_type, 0&gt;, public OptionalValue&lt;typename T2::parameter_type, 1&gt;{
public:
        typename boost::add_reference&lt;typename T1::parameter_type&gt;::type value1(){ return OptionalValue&lt;typename T1::parameter_type,0&gt;::value();}
        typename boost::add_reference&lt;typename T2::parameter_type&gt;::type value2(){ return OptionalValue&lt;typename T2::parameter_type,1&gt;::value();}
};

int main(){
        FooBar&lt;Foo&lt;int&gt;, Bar&gt; foobar1;
        int&amp; i = foobar1.value1();
        foobar1.value2();
        FooBar&lt;Bar, Foo&lt;double&gt; &gt; foobar2;
        foobar2.value1();
        double&amp; d = foobar2.value2();
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2047003</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2047003</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Sun, 10 Apr 2011 08:54:24 GMT</pubDate></item></channel></rss>