<?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[Generic Lambda factory delegates]]></title><description><![CDATA[<p>Aktuell versuche ich auf Basis von C++11 eine generische Lambda Delegate Factory<br />
umzusetzen, die es mir erlaubt Objekte ohne und mit verschiedenen Konstruktor<br />
Argumenten zu erzeugen. Dabei habe ich mich an folgendem Artikel orientiert:<br />
<a href="http://www.cprogramming.com/c++11/c++11-lambda-closures.html" rel="nofollow">http://www.cprogramming.com/c++11/c++11-lambda-closures.html</a></p>
<p>Den Artikel habe ich soweit verstanden. Und ich weiß, dass ich z.B. ein konkretes<br />
Objekt mit verschiedenen Delegates erzeugen kann:</p>
<pre><code>class ITest
{
public:
	ITest(const std::string&amp; text){
		m_text = text;
	}

	virtual ~ITest(){}

	virtual void saySomething(void) = 0;

protected:
	std::string m_text = &quot;undefined&quot;;
};

class Test : virtual public ITest
{
public:
	Test():ITest(&quot;Hi there!&quot;){}
	Test(const std::string&amp; text)
	:ITest(text){}

	Test(const std::string&amp; text, const std::string&amp; name)
	:ITest(text), m_name(name){
		m_text = text;
	}

	virtual void saySomething(void){

		std::string say; 
		if(m_name.compare(&quot;undefined&quot;)==0){
			say = &quot;I've to say: &quot;;
		}
		else if(m_name.compare(&quot;undefined&quot;)!=0){
			say = m_name + &quot; has to say: &quot;;
		}

		std::cout &lt;&lt; say &lt;&lt; m_text &lt;&lt; std::endl;
	}

private:
	std::string m_name = &quot;undefined&quot;;
};

int main()
{
	auto delegate = [&amp;]() -&gt; Test * {return new Test();};
	auto test = delegate();
	test-&gt;saySomething();

	auto delegate1 = [&amp;](const std::string&amp; text) -&gt; Test * {return new Test(text);};
	auto test1 = delegate1(&quot;I'm created by delegate&quot;);
	test1-&gt;saySomething();

	auto delegate2 = [&amp;](const std::string&amp; text, const std::string&amp; name) -&gt; Test * {return new Test(text, name);};
	auto test2 = delegate2(&quot;I'm also created by delegate&quot;, &quot;Tom&quot;);
	test2-&gt;saySomething();
	exit(0)
}
</code></pre>
<p>Und ich erhalte folgenden Output:</p>
<blockquote>
<p>$ ./bin/delegates.exe<br />
I've to say: Hi there!<br />
I've to say: I'm created by delegate<br />
Tom has to say: I'm also created by delegate</p>
</blockquote>
<p>Soweit prima. Doch nun möchte ich das ganze in eine generische Factory verpacken, bei der ich den<br />
jeweiligen konkreten Delegate zuvor registrieren kann um dann bei Bedarf mit 0...n Argumenten das<br />
Objekt dynamisch zur Laufzeit mit Laufzeitabhängigen Werten zu füllen.</p>
<p>Nur wie bekomme ich das hin? Ich habe gedacht ich nutze Variadic Templates und die std::function<br />
um dies zu realisieren. Hier mein erster, grober Entwurf:</p>
<pre><code>template&lt;class T, typename ... Args&gt;
class DelegateFactory
{
public:
	std::shared_ptr&lt;T&gt; create(Args&amp;&amp; ... args) const {
		return std::shared_ptr&lt;T&gt;(static_cast&lt;T*&gt;(m_delegate(std::forward&lt;Args&gt;(args)...)));
	}

	void registerDelegate(std::function&lt;T* (Args&amp;&amp; ... args)&gt; delegate)
	{
		 m_delegate = delegate;
	}	

private:	
	std::function&lt;T* (Args&amp;&amp; ... args)&gt; m_delegate = nullptr;
};

int main()
{
	// dies hier klappt noch ...
	auto fac = DelegateFactory&lt;Test&gt;();
	fac.registerDelegate(delegate);
	auto test3 = fac.create();
	test3-&gt;saySomething();

	// Und dieser nicht mehr
	auto fac1 = DelegateFactory&lt;Test&gt;();
	fac1.registerDelegate(delegate1);
	auto test4 = fac.create(&quot;I'm created by generic factory delegate&quot;);
	test4-&gt;saySomething();
	exit(0)
}
</code></pre>
<p>Hier einmal die Fehlermeldung:</p>
<blockquote>
<p>d:/tmp/test/samples/ioc/src/signals.cpp: In function 'int main()':<br />
d:/tmp/test/samples/ioc/src/signals.cpp:210:34: error: no matching function for call to 'DelegateFactory&lt;Test&gt;::registerDelegate(main()::&lt;lambda(const string&amp;)&gt;&amp;)'<br />
fac1.registerDelegate(delegate1);<br />
^<br />
d:/tmp/test/samples/ioc/src/signals.cpp:210:34: note: candidate is:<br />
d:/tmp/test/samples/ioc/src/signals.cpp:153:7: note: void DelegateFactory&lt;T, Args&gt;::registerDelegate(std::function&lt;T*(Args&amp;&amp; ...)&gt;) [with T = Test; Args = {}]<br />
void registerDelegate(std::function&lt;T* (Args&amp;&amp; ... args)&gt; delegate)<br />
^<br />
d:/tmp/test/samples/ioc/src/signals.cpp:153:7: note: no known conversion for argument 1 from 'main()::&lt;lambda(const string&amp;)&gt;' to 'std::function&lt;Test*()&gt;'<br />
d:/tmp/test/samples/ioc/src/signals.cpp:211:68: error: no matching function for call to 'DelegateFactory&lt;Test&gt;::create(const char [40])'<br />
auto test4 = fac.create(&quot;I'm created by generic factory delegate&quot;);<br />
^<br />
d:/tmp/test/samples/ioc/src/signals.cpp:211:68: note: candidate is:<br />
d:/tmp/test/samples/ioc/src/signals.cpp:149:21: note: std::shared_ptr&lt;_Tp1&gt; DelegateFactory&lt;T, Args&gt;::create(Args&amp;&amp; ...) const [with T = Test; Args = {}]<br />
std::shared_ptr&lt;T&gt; create(Args&amp;&amp; ... args) const {<br />
^<br />
d:/tmp/test/samples/ioc/src/signals.cpp:149:21: note: candidate expects 0 arguments, 1 provided</p>
</blockquote>
<p>Ist mein Ansatz überhaupt möglich? Wenn ja wie? Mein Ziel ist es, möglichst einfach Delegates<br />
zu definieren und generisch zu nutzen, da ich zur Laufzeit erst einen Zugriff auf die Parameter<br />
für den Konstruktor habe, die in Typ und Anzahl variieren können.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/328021/generic-lambda-factory-delegates</link><generator>RSS for Node</generator><lastBuildDate>Wed, 08 Jul 2026 16:08:55 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/328021.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 17 Sep 2014 12:03:07 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Generic Lambda factory delegates on Wed, 17 Sep 2014 12:03:07 GMT]]></title><description><![CDATA[<p>Aktuell versuche ich auf Basis von C++11 eine generische Lambda Delegate Factory<br />
umzusetzen, die es mir erlaubt Objekte ohne und mit verschiedenen Konstruktor<br />
Argumenten zu erzeugen. Dabei habe ich mich an folgendem Artikel orientiert:<br />
<a href="http://www.cprogramming.com/c++11/c++11-lambda-closures.html" rel="nofollow">http://www.cprogramming.com/c++11/c++11-lambda-closures.html</a></p>
<p>Den Artikel habe ich soweit verstanden. Und ich weiß, dass ich z.B. ein konkretes<br />
Objekt mit verschiedenen Delegates erzeugen kann:</p>
<pre><code>class ITest
{
public:
	ITest(const std::string&amp; text){
		m_text = text;
	}

	virtual ~ITest(){}

	virtual void saySomething(void) = 0;

protected:
	std::string m_text = &quot;undefined&quot;;
};

class Test : virtual public ITest
{
public:
	Test():ITest(&quot;Hi there!&quot;){}
	Test(const std::string&amp; text)
	:ITest(text){}

	Test(const std::string&amp; text, const std::string&amp; name)
	:ITest(text), m_name(name){
		m_text = text;
	}

	virtual void saySomething(void){

		std::string say; 
		if(m_name.compare(&quot;undefined&quot;)==0){
			say = &quot;I've to say: &quot;;
		}
		else if(m_name.compare(&quot;undefined&quot;)!=0){
			say = m_name + &quot; has to say: &quot;;
		}

		std::cout &lt;&lt; say &lt;&lt; m_text &lt;&lt; std::endl;
	}

private:
	std::string m_name = &quot;undefined&quot;;
};

int main()
{
	auto delegate = [&amp;]() -&gt; Test * {return new Test();};
	auto test = delegate();
	test-&gt;saySomething();

	auto delegate1 = [&amp;](const std::string&amp; text) -&gt; Test * {return new Test(text);};
	auto test1 = delegate1(&quot;I'm created by delegate&quot;);
	test1-&gt;saySomething();

	auto delegate2 = [&amp;](const std::string&amp; text, const std::string&amp; name) -&gt; Test * {return new Test(text, name);};
	auto test2 = delegate2(&quot;I'm also created by delegate&quot;, &quot;Tom&quot;);
	test2-&gt;saySomething();
	exit(0)
}
</code></pre>
<p>Und ich erhalte folgenden Output:</p>
<blockquote>
<p>$ ./bin/delegates.exe<br />
I've to say: Hi there!<br />
I've to say: I'm created by delegate<br />
Tom has to say: I'm also created by delegate</p>
</blockquote>
<p>Soweit prima. Doch nun möchte ich das ganze in eine generische Factory verpacken, bei der ich den<br />
jeweiligen konkreten Delegate zuvor registrieren kann um dann bei Bedarf mit 0...n Argumenten das<br />
Objekt dynamisch zur Laufzeit mit Laufzeitabhängigen Werten zu füllen.</p>
<p>Nur wie bekomme ich das hin? Ich habe gedacht ich nutze Variadic Templates und die std::function<br />
um dies zu realisieren. Hier mein erster, grober Entwurf:</p>
<pre><code>template&lt;class T, typename ... Args&gt;
class DelegateFactory
{
public:
	std::shared_ptr&lt;T&gt; create(Args&amp;&amp; ... args) const {
		return std::shared_ptr&lt;T&gt;(static_cast&lt;T*&gt;(m_delegate(std::forward&lt;Args&gt;(args)...)));
	}

	void registerDelegate(std::function&lt;T* (Args&amp;&amp; ... args)&gt; delegate)
	{
		 m_delegate = delegate;
	}	

private:	
	std::function&lt;T* (Args&amp;&amp; ... args)&gt; m_delegate = nullptr;
};

int main()
{
	// dies hier klappt noch ...
	auto fac = DelegateFactory&lt;Test&gt;();
	fac.registerDelegate(delegate);
	auto test3 = fac.create();
	test3-&gt;saySomething();

	// Und dieser nicht mehr
	auto fac1 = DelegateFactory&lt;Test&gt;();
	fac1.registerDelegate(delegate1);
	auto test4 = fac.create(&quot;I'm created by generic factory delegate&quot;);
	test4-&gt;saySomething();
	exit(0)
}
</code></pre>
<p>Hier einmal die Fehlermeldung:</p>
<blockquote>
<p>d:/tmp/test/samples/ioc/src/signals.cpp: In function 'int main()':<br />
d:/tmp/test/samples/ioc/src/signals.cpp:210:34: error: no matching function for call to 'DelegateFactory&lt;Test&gt;::registerDelegate(main()::&lt;lambda(const string&amp;)&gt;&amp;)'<br />
fac1.registerDelegate(delegate1);<br />
^<br />
d:/tmp/test/samples/ioc/src/signals.cpp:210:34: note: candidate is:<br />
d:/tmp/test/samples/ioc/src/signals.cpp:153:7: note: void DelegateFactory&lt;T, Args&gt;::registerDelegate(std::function&lt;T*(Args&amp;&amp; ...)&gt;) [with T = Test; Args = {}]<br />
void registerDelegate(std::function&lt;T* (Args&amp;&amp; ... args)&gt; delegate)<br />
^<br />
d:/tmp/test/samples/ioc/src/signals.cpp:153:7: note: no known conversion for argument 1 from 'main()::&lt;lambda(const string&amp;)&gt;' to 'std::function&lt;Test*()&gt;'<br />
d:/tmp/test/samples/ioc/src/signals.cpp:211:68: error: no matching function for call to 'DelegateFactory&lt;Test&gt;::create(const char [40])'<br />
auto test4 = fac.create(&quot;I'm created by generic factory delegate&quot;);<br />
^<br />
d:/tmp/test/samples/ioc/src/signals.cpp:211:68: note: candidate is:<br />
d:/tmp/test/samples/ioc/src/signals.cpp:149:21: note: std::shared_ptr&lt;_Tp1&gt; DelegateFactory&lt;T, Args&gt;::create(Args&amp;&amp; ...) const [with T = Test; Args = {}]<br />
std::shared_ptr&lt;T&gt; create(Args&amp;&amp; ... args) const {<br />
^<br />
d:/tmp/test/samples/ioc/src/signals.cpp:149:21: note: candidate expects 0 arguments, 1 provided</p>
</blockquote>
<p>Ist mein Ansatz überhaupt möglich? Wenn ja wie? Mein Ziel ist es, möglichst einfach Delegates<br />
zu definieren und generisch zu nutzen, da ich zur Laufzeit erst einen Zugriff auf die Parameter<br />
für den Konstruktor habe, die in Typ und Anzahl variieren können.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2417987</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2417987</guid><dc:creator><![CDATA[Snoob]]></dc:creator><pubDate>Wed, 17 Sep 2014 12:03:07 GMT</pubDate></item><item><title><![CDATA[Reply to Generic Lambda factory delegates on Wed, 17 Sep 2014 19:01:37 GMT]]></title><description><![CDATA[<p>Snoob schrieb:</p>
<blockquote>
<p>eine generische Lambda Delegate Factory</p>
</blockquote>
<p>da geht noch mehr. Echte Profis verwenden generische Lambda Delegate Factory Provider Service Adapter Facaden um die grenzenlosen Synergieeffekte der Objektorientierung vollständig zu nutzen.</p>
<pre><code>auto fac1 = DelegateFactory&lt;Test, std::string&gt;(); 
auto test4 = fac1.create(&quot;I'm created by generic factory delegate&quot;);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2418042</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2418042</guid><dc:creator><![CDATA[bla123]]></dc:creator><pubDate>Wed, 17 Sep 2014 19:01:37 GMT</pubDate></item><item><title><![CDATA[Reply to Generic Lambda factory delegates on Thu, 18 Sep 2014 07:09:26 GMT]]></title><description><![CDATA[<p>Danke für den Hinweis. Ok, für den Funktkionspointer muss ich explizit die Argumente mit angeben. D.h. ich brauche je nach Konstruktor Ausprägung exakt eine DelegatFactory ...</p>
<blockquote>
<p>Echte Profis verwenden generische Lambda Delegate Factory Provider Service Adapter Facaden</p>
</blockquote>
<p>Klingt interessant. Hast Du evtl. ein Link wo dazu mehr Infos bekomme, bzw. wo ich mir das einmal exemplarisch, gern auch als Pseudo-Code verinnerlichen kann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2418081</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2418081</guid><dc:creator><![CDATA[Snoob]]></dc:creator><pubDate>Thu, 18 Sep 2014 07:09:26 GMT</pubDate></item><item><title><![CDATA[Reply to Generic Lambda factory delegates on Thu, 18 Sep 2014 08:10:21 GMT]]></title><description><![CDATA[<p>Snoob schrieb:</p>
<blockquote>
<p>Danke für den Hinweis. Ok, für den Funktkionspointer muss ich explizit die Argumente mit angeben. D.h. ich brauche je nach Konstruktor Ausprägung exakt eine DelegatFactory ...</p>
</blockquote>
<p>naja, wenn man mal das ganze delegate factory Zeug ignoriert, steht da einfach ein Klassentemplate:</p>
<pre><code>template&lt;class T, typename ... Args&gt;
class DelegateFactory 
// ....
// much later:
DelegateFactory&lt;Test&gt; // jetzt steht der Typ fest und Args... ist leer
</code></pre>
<p>Snoob schrieb:</p>
<blockquote>
<blockquote>
<p>Echte Profis verwenden generische Lambda Delegate Factory Provider Service Adapter Facaden</p>
</blockquote>
<p>Klingt interessant. Hast Du evtl. ein Link wo dazu mehr Infos bekomme, bzw. wo ich mir das einmal exemplarisch, gern auch als Pseudo-Code verinnerlichen kann?</p>
</blockquote>
<p>not sure if well played or broken irony detector</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2418089</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2418089</guid><dc:creator><![CDATA[bla123]]></dc:creator><pubDate>Thu, 18 Sep 2014 08:10:21 GMT</pubDate></item><item><title><![CDATA[Reply to Generic Lambda factory delegates on Thu, 18 Sep 2014 09:35:14 GMT]]></title><description><![CDATA[<blockquote>
<pre><code>DelegateFactory&lt;Test&gt; // jetzt steht der Typ fest und Args... ist leer
</code></pre>
</blockquote>
<p>Das meinte ich ja, bei der Konkreten Definition der Template Ausprägung muss ich mit angeben ob ich wie oben keine Args habe, oder entsprechend genau die Ausprägung.</p>
<p>D.h. um alle 3 Konstruktoren von Test bedienen zu können, benötige ich exakt 3 Definitionen:</p>
<pre><code>DelegateFactory&lt;Test&gt;()  //Ohne Argumente
DelegateFactory&lt;Test, const std::string&amp;&gt;()  //Ein Konstruktor Argument
DelegateFactory&lt;Test, const std::string&amp;, const std::string&amp;&gt;(); // //Zwei Argumente
</code></pre>
<p>Oder meintest Du was anderes ?</p>
<blockquote>
<p>not sure if well played or broken irony detector</p>
</blockquote>
<p><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>
]]></description><link>https://www.c-plusplus.net/forum/post/2418109</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2418109</guid><dc:creator><![CDATA[Snoob]]></dc:creator><pubDate>Thu, 18 Sep 2014 09:35:14 GMT</pubDate></item><item><title><![CDATA[Reply to Generic Lambda factory delegates on Thu, 18 Sep 2014 13:12:52 GMT]]></title><description><![CDATA[<p>Nachdem die Factory nun funktioniert, stellt sich mir die Frage, wie bekomme ich die in einen STL Container?</p>
<p>Normalerweise müsste ich ein Interface für die Factory definieren, das kein Klassentemplate ist. Nur wie bekomme ich in dieses Interface eine generische, virtuelle Methode zum Aufruf des Lambda Delegators hin?</p>
<pre><code>class IDelegateFactory
{
public:
	IDelegateFactory(){}
	virtual ~IDelegateFactory(){}

	template &lt;class T, typename ... Args&gt;
	std::shared_ptr&lt;T&gt; create(Args&amp;&amp; ... args) const {
            //Wie bekomme ich den Aufruf an den Delegator in der konkreten Factory hin?
            return this-&gt;delegate(args);
	}

private:
	virtual std::shared_ptr&lt;void&gt; delegate(????) = 0;
};
</code></pre>
<p>Den Das Interface hat ja keinen Zugriff auf den Delegator der als std::function in der konkreten Klasse definiert ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2418167</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2418167</guid><dc:creator><![CDATA[Snoob]]></dc:creator><pubDate>Thu, 18 Sep 2014 13:12:52 GMT</pubDate></item></channel></rss>