<?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[Regestrierung von Template Klassen während Compile-Time]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich möchte gerne Template Klassen während Compile-Time registrieren um sie später via Namen instanzieren zu können.<br />
Ich hab mir dazu bereits einige Lösungen im Internet angeschaut, leider aber keine passende gefunden.<br />
Die vielverspechenste Lösung, die ich fand, ist diese:</p>
<pre><code>struct MyClasses {
    static vector&lt;string&gt; myclasses;
    MyClasses(string name) { myclasses.push_back(name); }
};

#define REGISTER_CLASS(cls) static MyClasses myclass_##cls(#cls);

struct XYZ {
};

REGISTER_CLASS(XYZ);
</code></pre>
<p>Allerdings schreibt der Autor der Lösung:</p>
<blockquote>
<p>I don't think it will work for templates, though.</p>
</blockquote>
<p>Mein SourceCode nutzt aber Templates. Ich hab nun folgendes probiert, aber es klappt nicht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
<pre><code>template&lt;typename TF&gt;
        class AbstractFilter : public IFilter&lt;TF&gt;
        {
        public:

            template&lt;typename T&gt; static IFilter&lt;TF&gt;* createTemplate() {return new T;}

            struct FilterFactory
            {
                typedef boost::unordered_map&lt;std::string, IFilter&lt;TF&gt;*(*)()&gt; FilterMap;

            protected:
                static FilterMap* getMap()
                {
                    static FilterMap filters;
                    return &amp;filters;
                }
            };

            virtual bool process(TF *data) = 0;
        };

#define REGISTER_CLASS(cls) template&lt;typename TF&gt; static typename AbstractFilter&lt;TF&gt;::FilterFactory filters_##cls(#cls);
</code></pre>
<p>Könnt ihr mir sagen, was ich ändern muss, um die obrige Lösung für Templates anzupassen?</p>
<p>LG<br />
Daniel</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/318958/regestrierung-von-template-klassen-während-compile-time</link><generator>RSS for Node</generator><lastBuildDate>Sun, 26 Jul 2026 15:02:50 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/318958.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 01 Aug 2013 13:37:37 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Regestrierung von Template Klassen während Compile-Time on Thu, 01 Aug 2013 13:37:37 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich möchte gerne Template Klassen während Compile-Time registrieren um sie später via Namen instanzieren zu können.<br />
Ich hab mir dazu bereits einige Lösungen im Internet angeschaut, leider aber keine passende gefunden.<br />
Die vielverspechenste Lösung, die ich fand, ist diese:</p>
<pre><code>struct MyClasses {
    static vector&lt;string&gt; myclasses;
    MyClasses(string name) { myclasses.push_back(name); }
};

#define REGISTER_CLASS(cls) static MyClasses myclass_##cls(#cls);

struct XYZ {
};

REGISTER_CLASS(XYZ);
</code></pre>
<p>Allerdings schreibt der Autor der Lösung:</p>
<blockquote>
<p>I don't think it will work for templates, though.</p>
</blockquote>
<p>Mein SourceCode nutzt aber Templates. Ich hab nun folgendes probiert, aber es klappt nicht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
<pre><code>template&lt;typename TF&gt;
        class AbstractFilter : public IFilter&lt;TF&gt;
        {
        public:

            template&lt;typename T&gt; static IFilter&lt;TF&gt;* createTemplate() {return new T;}

            struct FilterFactory
            {
                typedef boost::unordered_map&lt;std::string, IFilter&lt;TF&gt;*(*)()&gt; FilterMap;

            protected:
                static FilterMap* getMap()
                {
                    static FilterMap filters;
                    return &amp;filters;
                }
            };

            virtual bool process(TF *data) = 0;
        };

#define REGISTER_CLASS(cls) template&lt;typename TF&gt; static typename AbstractFilter&lt;TF&gt;::FilterFactory filters_##cls(#cls);
</code></pre>
<p>Könnt ihr mir sagen, was ich ändern muss, um die obrige Lösung für Templates anzupassen?</p>
<p>LG<br />
Daniel</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2342764</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2342764</guid><dc:creator><![CDATA[daniel_c++]]></dc:creator><pubDate>Thu, 01 Aug 2013 13:37:37 GMT</pubDate></item><item><title><![CDATA[Reply to Regestrierung von Template Klassen während Compile-Time on Thu, 01 Aug 2013 14:11:39 GMT]]></title><description><![CDATA[<p>Könnte im Prinzip so aussehen:</p>
<pre><code class="language-cpp">#include &lt;vector&gt;
#include &lt;typeinfo&gt;
#include &lt;string&gt;

using namespace std;;

struct MyClasses {
    static vector&lt;string&gt; myclasses;
    MyClasses(string name) { myclasses.push_back(name); }
};
vector&lt;string&gt; MyClasses::myclasses;

template &lt;typename T&gt;
struct foo
{
    static const MyClasses reg;
    char dummy[&amp;reg!=0];
};
template &lt;typename T&gt;
const MyClasses foo&lt;T&gt;::reg(string(&quot;foo&lt;&quot;)+typeid(T).name()+string(&quot;&gt;&quot;));

#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;algorithm&gt;
int main()
{
    (void)sizeof(foo&lt;int&gt;); // implizite Instantiierung von foo&lt;int&gt; - ein explizite Instantiierung würde nichts demonstrieren, weil eine solche immer automatisch alle Member instantiiert
    copy(MyClasses::myclasses.begin(),MyClasses::myclasses.end(),ostream_iterator&lt;string&gt;(cout,&quot;\n&quot;));
}
</code></pre>
<p>Statische Member werden nur instanziiert, wenn sie auch existieren müssen. dummy koppelt hier die implizite Instanziierung des statischen Members reg an die Instanziierung der Klasse foo&lt;T&gt;, in der Praxis wäre es wahrscheinlich besser, an die Instantiierung einer Memberfunktion (Konstruktor,Destruktor) zu koppeln - jedenfalls dann, wenn diese sowieso selbst geschrieben werden müssen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2342769</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2342769</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 01 Aug 2013 14:11:39 GMT</pubDate></item><item><title><![CDATA[Reply to Regestrierung von Template Klassen während Compile-Time on Fri, 02 Aug 2013 06:58:29 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>zunächst mal Danke für deine Antwort.<br />
Aber ich verstehe die Lösung nicht 100%-ig und auch nicht wie ich sie auf meinenen Code umsezten kann.<br />
Ich versuche mein derzeitigen Code nochmal etwas detailierter zu erklären und vielleicht könntest du dann explizit darauf eingehn.</p>
<p>Zunächst erkläre ich die Klasse AbstractFilter etwas besser:</p>
<pre><code>//AbstractFilter.hpp

// Die AbstractFilter Klasse ist zuständig für die Bereitstellung der Factory sowie für das entgegenehmen von Regestrierungen.
// Sie ist selbst eine Template Klasse
template&lt;typename TF&gt;
        class AbstractFilter : public IFilter&lt;TF&gt;
        {
        public:
            template&lt;typename T&gt; static IFilter&lt;TF&gt;* createTemplate() {return new T;}
            struct FilterFactory
            {
                // Diese Map legt das mapping zwischen Namen und Konstruktoren fest.
                typedef boost::unordered_map&lt;std::string, IFilter&lt;TF&gt;*(*)()&gt; FilterMap;

                // Die Factory kann durch einen Table-Lookup die konkrete Klasse instanzieren.
                static IFilter&lt;TF&gt;* createFilterInstance(const std::string &amp;name)
                {
                    typename FilterMap::iterator it = getMap()-&gt;find(name);
                    if(it != getMap()-&gt;end())
                        return it-&gt;second();
                    else
                        return NULL;
                }

            protected:
                //Statische Methode zur erzeugung der FilterMap
                static FilterMap* getMap()
                {
                    static FilterMap filters;
                    return &amp;filters;
                }
            };

            // Der FilterRegister ist für die entgegenahme von Registrierungen zuständig.
            template&lt;typename T&gt;
            struct FilterRegister : FilterFactory
            {
                FilterRegister(const std::string&amp; name)
                {
                    fprintf(stderr, &quot;Registered Filter: %s\n&quot;, name.c_str());
                    FilterFactory::getMap()-&gt;insert(typename FilterFactory::FilterMap::value_type(name, &amp;createTemplate&lt;Td&gt;));
                }
            };

            // Pure virtual Function. Verarbeitet Daten beliebigen Typs.
            virtual bool process(TF *data) = 0;
        };
</code></pre>
<p>So, die konkrete Implementierung eines Filters schaut zb. folgend aus:</p>
<pre><code>//SampleFilter.h

class SampleFilter : public AbstractFilter&lt;std::string&gt;
        {
            public:
                SampleFilter();
                bool process(std::string *data);

            private:
                static FilterRegister&lt;SampleFilter&gt; reg;
        };
</code></pre>
<pre><code>//SampleFilter.cc

#include &quot;samplefilter.h&quot;

using namespace ccns::processing;

//Diese Initialisierung sollte die Klasse SampleFilter registrieren.
typename ccns::processing::AbstractFilter&lt;std::string&gt;::FilterRegister&lt;SampleFilter&gt; SampleFilter::reg(std::string(&quot;SampleFilter&quot;));

SampleFilter::SampleFilter()
{
}

bool SampleFilter::process(std::string *data)
{
    fprintf(stderr, &quot;Processcing Data = %s...\n&quot;,data-&gt;c_str());
    return true;
}
</code></pre>
<p>Zur Verwendung:</p>
<pre><code>//main.c

    PipelineManager&lt;std::string&gt; *man = PipelineFactory&lt;std::string&gt;::CreateFromConfig(pipelinename,file);

    //SampleFilter f;  

    std::string data(&quot;thats a test string&quot;);
    man-&gt;executeChain(&amp;data); //findet den Samplefilter nur wenn Zeile 5 aufgerufen wird.
</code></pre>
<p>Das Problem ist offensichtlich. Die Klasse SampleFilter wird nie verwendet vor dem Aufruf von executeChain().<br />
Deshalb kann sie sich auch nicht in der FilterMap registrieren.<br />
Könntest du vielleicht an meinen Code andeuten wie ich deine Lösung in meinen Code integrieren kann?</p>
<p>LG und vielen Dank nochmal,<br />
Daniel</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2342861</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2342861</guid><dc:creator><![CDATA[daniel_c++]]></dc:creator><pubDate>Fri, 02 Aug 2013 06:58:29 GMT</pubDate></item></channel></rss>