<?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[functor_traits und lambda_traits]]></title><description><![CDATA[<p>Meine Klassen function_traits und method_traits funktionieren schon wunderbar (in C++03). Nun wollte ich noch die beiden im Titel angedeuteten Klassen schreiben. Wie die Klassen etwa aussehen sollten:</p>
<pre><code>template&lt;typename T&gt;
	struct functor_traits
	{
		static const bool is_functor;

		static const bool has_nonconst_nonvolatile;
		static const bool has_const_nonvolatile;
		static const bool has_nonconst_volatile;
		static const bool has_const_volatile; //Bezeichnen, ob der operator() auch aus z.B. const volatile Funktoren aus aufgerufen werden kann

		typedef void return_type;

		static const std::size_t parameter_count;
	};
</code></pre>
<p>functor_traits sollte in C++03 gemacht werden (muss jedoch nur max. 20 Argumente unterstützen, den Code kann ich mir dann generieren lassen). Zu dem habe ich leider noch gar nicht hinbekommen, ich habe keine Idee wie man das angehen soll. (Wieso kann ich den operator() nicht als Methodenzeiger speichern?)<br />
lambda_traits kann selbstverständlich in C++11 gemacht werden. Bei dem hab ich schon ganz ganz wenig:</p>
<pre><code>template&lt;typename T&gt;
	class lambda_traits
	{
		struct true_type
		{
			char a[1];
		};
		struct false_type
		{
			char a[2];
		};

		template&lt;typename U&gt;
		static true_type check(decltype(std::declval&lt;U&gt;()())*);

		template&lt;typename U&gt;
		static false_type check(...);

	public:
		static const bool is_lambda = sizeof(check&lt;T&gt;(0)) == sizeof(true_type);

		//typedef void return_type;

		//static const std::size_t parameter_count = ;
	};
</code></pre>
<p>Davor wird erst noch geprüft ob T ein Funktor / eine Funktion ist. Das hier funktioniert leider nur für Lambdas ohne Parameter. Zudem weiß ich nicht, ob declval mit einem Lambdatypen erlaubt ist.</p>
<p>Kann mir einer hierbei helfen? Ich komme echt nicht weiter.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/327479/functor_traits-und-lambda_traits</link><generator>RSS for Node</generator><lastBuildDate>Wed, 08 Jul 2026 23:52:58 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/327479.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 14 Aug 2014 09:12:14 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to functor_traits und lambda_traits on Thu, 14 Aug 2014 09:12:14 GMT]]></title><description><![CDATA[<p>Meine Klassen function_traits und method_traits funktionieren schon wunderbar (in C++03). Nun wollte ich noch die beiden im Titel angedeuteten Klassen schreiben. Wie die Klassen etwa aussehen sollten:</p>
<pre><code>template&lt;typename T&gt;
	struct functor_traits
	{
		static const bool is_functor;

		static const bool has_nonconst_nonvolatile;
		static const bool has_const_nonvolatile;
		static const bool has_nonconst_volatile;
		static const bool has_const_volatile; //Bezeichnen, ob der operator() auch aus z.B. const volatile Funktoren aus aufgerufen werden kann

		typedef void return_type;

		static const std::size_t parameter_count;
	};
</code></pre>
<p>functor_traits sollte in C++03 gemacht werden (muss jedoch nur max. 20 Argumente unterstützen, den Code kann ich mir dann generieren lassen). Zu dem habe ich leider noch gar nicht hinbekommen, ich habe keine Idee wie man das angehen soll. (Wieso kann ich den operator() nicht als Methodenzeiger speichern?)<br />
lambda_traits kann selbstverständlich in C++11 gemacht werden. Bei dem hab ich schon ganz ganz wenig:</p>
<pre><code>template&lt;typename T&gt;
	class lambda_traits
	{
		struct true_type
		{
			char a[1];
		};
		struct false_type
		{
			char a[2];
		};

		template&lt;typename U&gt;
		static true_type check(decltype(std::declval&lt;U&gt;()())*);

		template&lt;typename U&gt;
		static false_type check(...);

	public:
		static const bool is_lambda = sizeof(check&lt;T&gt;(0)) == sizeof(true_type);

		//typedef void return_type;

		//static const std::size_t parameter_count = ;
	};
</code></pre>
<p>Davor wird erst noch geprüft ob T ein Funktor / eine Funktion ist. Das hier funktioniert leider nur für Lambdas ohne Parameter. Zudem weiß ich nicht, ob declval mit einem Lambdatypen erlaubt ist.</p>
<p>Kann mir einer hierbei helfen? Ich komme echt nicht weiter.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413417</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413417</guid><dc:creator><![CDATA[Abrakadabra]]></dc:creator><pubDate>Thu, 14 Aug 2014 09:12:14 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Thu, 14 Aug 2014 09:24:25 GMT]]></title><description><![CDATA[<p>Könntest du mal ein Beispiel geben, was das am Schluss können soll? Geht es nur um Funktionen ohne Argumente? Wie wird es benutzt?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413421</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413421</guid><dc:creator><![CDATA[smartquestions]]></dc:creator><pubDate>Thu, 14 Aug 2014 09:24:25 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Thu, 14 Aug 2014 09:42:18 GMT]]></title><description><![CDATA[<p>&quot;muss jedoch nur max. 20 Argumente unterstützen, den Code kann ich mir dann generieren lassen&quot;. Geht also auch um Funktoren und Lambdas mit Parametern (parameter_count würde ansonsten ja auch gar keinen Sinn ergeben).</p>
<p>Was es können soll steht im Code schon etwa drin. Einsetzen kann man es z.B. in etwa so:</p>
<pre><code>template&lt;typename T&gt;
struct result_of
{
	typedef typename conditional&lt;function_traits&lt;T&gt;::is_function, function_traits&lt;T&gt;::return_type,
			typename conditional&lt;method_traits&lt;T&gt;::is_method, method_traits&lt;T&gt;::return_type,
			typename conditional&lt;functor_traits&lt;T&gt;::is_functor, functor_traits&lt;T&gt;::return_type, /*Felertyp*/&gt;::type&gt;::type&gt;::type type;
};

template&lt;typename T&gt;
struct varcall
{
	T fnc;

	explicit varcall(T fnc) : fnc(fnc) {}

	operator typename result_of&lt;T&gt;::type () { return fnc(); }
};

template&lt;typename T&gt;
varcall&lt;T&gt; fnc_to_var(T fnc)
{
	return varcall&lt;T&gt;(fnc);
}

int main()
{
	std::vector&lt;int&gt; vec(1000);
	std::fill(vec.begin(), vec.end(), fnc_to_var(&amp;std::rand)); //Ich kenne std::generate, das ist nur ein Anwendungsbeispiel
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2413423</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413423</guid><dc:creator><![CDATA[Abrakadabra]]></dc:creator><pubDate>Thu, 14 Aug 2014 09:42:18 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Thu, 14 Aug 2014 18:07:31 GMT]]></title><description><![CDATA[<blockquote>
<p>Zudem weiß ich nicht, ob declval mit einem Lambdatypen erlaubt ist.</p>
</blockquote>
<p>Hier liegt dein Denkproblem - ein Lambda ist nichts weiter als ein Klassenobjekt.<br />
Du kannst nicht prüfen ob ein Funktionsobjekt ein Lambda ist - genauso wenig wie du prüfen kannst ob ein Funktionsobjekt-Typ ein closure-Typ ist.</p>
<p>Dein Code ist auch teils falsch - was wenn <code>decltype(std::declval&lt;U&gt;()())</code> eine Referenztyp ist?</p>
<p>Um zu prüfen ob ein Typ eine Klasse mit überladenem <code>operator()</code> ist, nutz sowas:</p>
<pre><code>template&lt;typename U&gt;
	static std::true_type check(decltype(&amp;U::operator()));

	template&lt;typename&gt;
	static std::false_type check(...);

public:

	static const bool is_functor = decltype(check&lt;T&gt;(0))::value;
</code></pre>
<p>Es gibt aber selbstverständlich auch Probleme mit diesem Code - zum Beispiel könnte der <code>operator()</code> auch ein <strong>Funktionstemplate</strong> sein. Es ist AFAIK unmöglich jeden Funktionsobjekt-Typ als solchen feststellen zu können, selbst wenn man sich auf eine Parameterzahl beschränkt.</p>
<p>Falls du also den Template-fall weglässt lässt sich <code>functor_traits</code> recht einfach (durch partielle Spezialisierungen) implementieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413519</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413519</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Thu, 14 Aug 2014 18:07:31 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Fri, 15 Aug 2014 06:05:23 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>Hier liegt dein Denkproblem - ein Lambda ist nichts weiter als ein Klassenobjekt.</p>
</blockquote>
<p>Ist es daher instanziierbar?</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Du kannst nicht prüfen ob ein Funktionsobjekt ein Lambda ist - genauso wenig wie du prüfen kannst ob ein Funktionsobjekt-Typ ein closure-Typ ist.</p>
</blockquote>
<p>Was ist ein closure-Typ?</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Dein Code ist auch teils falsch - was wenn <code>decltype(std::declval&lt;U&gt;()())</code> eine Referenztyp ist?</p>
</blockquote>
<p>Stimmt, daran dachte ich nicht. Macht <code>std::remove_reference</code> den Trick?</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Um zu prüfen ob ein Typ eine Klasse mit überladenem <code>operator()</code> ist, nutz sowas:</p>
<pre><code>template&lt;typename U&gt;
	static std::true_type check(decltype(&amp;U::operator()));

	template&lt;typename&gt;
	static std::false_type check(...);

public:

	static const bool is_functor = decltype(check&lt;T&gt;(0))::value;
</code></pre>
<p>Geht das irgendwie auch in C++03?</p>
</blockquote>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Es gibt aber selbstverständlich auch Probleme mit diesem Code - zum Beispiel könnte der <code>operator()</code> auch ein <strong>Funktionstemplate</strong> sein.</p>
</blockquote>
<p>Stimmt, daran dachte ich ebenfalls nicht.</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Falls du also den Template-fall weglässt lässt sich <code>functor_traits</code> recht einfach (durch partielle Spezialisierungen) implementieren.</p>
</blockquote>
<p>Auch in C++03? Könntest du das in groben Zügen zeigen? Ich kann's mir leider echt nicht vorstellen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413563</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413563</guid><dc:creator><![CDATA[Abrakadabra]]></dc:creator><pubDate>Fri, 15 Aug 2014 06:05:23 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 09:39:57 GMT]]></title><description><![CDATA[<blockquote>
<p>Macht <code>std::remove_reference</code> den Trick?</p>
</blockquote>
<p>Das gibt es aber doch erst seit C++11.</p>
<blockquote>
<p>Was ist ein closure-Typ?</p>
</blockquote>
<p>Der Typ eines Lambdas - also die Klasse dessen Objekt es ist.</p>
<blockquote>
<p>Geht das irgendwie auch in C++03?</p>
</blockquote>
<p>Wie wärs mit</p>
<pre><code>template &lt;void*&gt;
    struct Nothing
    {
        typedef char type;
    };

    template &lt;typename U&gt;
    static typename Nothing&lt;&amp;U::operator()&gt;::type check(int);

    template &lt;typename&gt;
    static int check(char);

public:

    static const bool is_functor = sizeof(check&lt;T&gt;(0)) == 1;
</code></pre>
<blockquote>
<p>Könntest du das in groben Zügen zeigen?</p>
</blockquote>
<p>Ist eklig mit C++03. Hast du Boost.PP zur Verfügung?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413681</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413681</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sat, 16 Aug 2014 09:39:57 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 10:06:14 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>Macht <code>std::remove_reference</code> den Trick?</p>
</blockquote>
<p>Das gibt es aber doch erst seit C++11.</p>
</blockquote>
<p>Und nahezu trivial zu implementieren, für vor C++11.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413684</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413684</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Sat, 16 Aug 2014 10:06:14 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 12:24:42 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>Macht <code>std::remove_reference</code> den Trick?</p>
</blockquote>
<p>Das gibt es aber doch erst seit C++11.</p>
</blockquote>
<p>Joa schon, ich habe es aber auch in C++03 implementiert mit partieller Spezialisierung.</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Wie wärs mit</p>
<pre><code>template &lt;void*&gt;
    struct Nothing
    {
        typedef char type;
    };
 
    template &lt;typename U&gt;
    static typename Nothing&lt;&amp;U::operator()&gt;::type check(int);
 
    template &lt;typename&gt;
    static int check(char);
 
public:
 
    static const bool is_functor = sizeof(check&lt;T&gt;(0)) == 1;
</code></pre>
</blockquote>
<p>Sieht zwar sehr gut aus, geht aber leider irgendwie nicht: <a href="http://ideone.com/LEJVUl" rel="nofollow">http://ideone.com/LEJVUl</a><br />
Mache ich etwas falsch?</p>
<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>Könntest du das in groben Zügen zeigen?</p>
</blockquote>
<p>Ist eklig mit C++03. Hast du Boost.PP zur Verfügung?</p>
</blockquote>
<p>Ist egal ob's eklig wird oder nicht. Boost wollte ich eigentlich nicht verwenden (einiges davon gibt's da ja eh schon fertig glaube ich).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413690</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413690</guid><dc:creator><![CDATA[Abrakadabra]]></dc:creator><pubDate>Sat, 16 Aug 2014 12:24:42 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 12:55:07 GMT]]></title><description><![CDATA[<p>Du kannst keine Funktionspointer implizit nach void* konvertieren.<br />
Wieso so check-Dinger nicht gehen, kannste gut erkennen indem du den default-Fall deaktivierst.<br />
Übrigens: int kann genauso groß sein wie char.<br />
Nimm besser char und char[2] oder so.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413692</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413692</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Sat, 16 Aug 2014 12:55:07 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 13:03:05 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>Wie wärs mit</p>
<pre><code>template &lt;void*&gt;
    struct Nothing
    {
        typedef char type;
    };
 
    template &lt;typename U&gt;
    static typename Nothing&lt;&amp;U::operator()&gt;::type check(int);
 
    template &lt;typename&gt;
    static int check(char);
 
public:
 
    static const bool is_functor = sizeof(check&lt;T&gt;(0)) == 1;
</code></pre>
</blockquote>
<p>Weder Funktionszeiger noch Zeiger auf Member sind implizit in void* konvertierbar.<br />
Schnell hingeschrieben könnte es <a href="http://ideone.com/C4XVax" rel="nofollow">so</a> funktionieren. Kann man noch etwas vereinfachen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413693</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413693</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Sat, 16 Aug 2014 13:03:05 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 15:27:27 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Schnell hingeschrieben könnte es <a href="http://ideone.com/C4XVax" rel="nofollow">so</a> funktionieren.</p>
</blockquote>
<p>Völlig irre! Warum sind die Rückgabetypen Referenzen?</p>
<p>Ich schlage als korrigierte Version</p>
<pre><code>template&lt;typename T&gt;
class test
{
	template &lt;int&gt;
	struct Nothing {typedef char type;};

	template &lt;typename U&gt;
	static typename Nothing&lt;sizeof(&amp;U::operator())&gt;::type check(int);

	template &lt;typename&gt;
	static int check(char);

public:

	static const bool is_functor = sizeof(check&lt;T&gt;(0)) == 1;
};
</code></pre>
<p>vor.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413698</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413698</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sat, 16 Aug 2014 15:27:27 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 15:58:33 GMT]]></title><description><![CDATA[<pre><code>template&lt;typename T&gt;
class test
{
	template &lt;int&gt;//int rein =&gt; char raus.
	struct Nothing {typedef char type;};

	template &lt;typename U&gt;//int rein =&gt; char raus.
	static typename Nothing&lt;sizeof(&amp;U::operator())&gt;::type check(int);

	template &lt;typename&gt;//char rein =&gt; int raus.
	static int check(char);

public:

	static const bool is_functor = sizeof(check&lt;T&gt;(0)) == 1;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2413699</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413699</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 16 Aug 2014 15:58:33 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 16:23:24 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<pre><code>template&lt;typename T&gt;
class test
{
	template &lt;int&gt;//int rein =&gt; char raus.
	struct Nothing {typedef char type;};

	template &lt;typename U&gt;//int rein =&gt; char raus.
	static typename Nothing&lt;sizeof(&amp;U::operator())&gt;::type check(int);

	template &lt;typename&gt;//char rein =&gt; int raus.
	static int check(char);

public:

	static const bool is_functor = sizeof(check&lt;T&gt;(0)) == 1;
};
</code></pre>
</blockquote>
<p>?<br />
Das ist Absicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413707</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413707</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Sat, 16 Aug 2014 16:23:24 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 16:31:19 GMT]]></title><description><![CDATA[<p>Nathan schrieb:</p>
<blockquote>
<p>Das ist Absicht.</p>
</blockquote>
<p>Ist es notwendig?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413711</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413711</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 16 Aug 2014 16:31:19 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 16:57:08 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>Nathan schrieb:</p>
<blockquote>
<p>Das ist Absicht.</p>
</blockquote>
<p>Ist es notwendig?</p>
</blockquote>
<p>Ja.<br />
Der unterschiedlich Rückgabewert weil sonst sizeof auf den Rückgabewert nicht funktioniert um die ausgewählte Funktion zu bestimmen und der unterschiedliche Paramter, damit die char-Version wenn man sie mit einem int aufruft, geringere Priorität wegen der Konvertierung nach char hat, als die andere Funktion, die man direkt mit einem int aufrufen kann. Ansonsten hätte man eine Ambiguität.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413713</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413713</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Sat, 16 Aug 2014 16:57:08 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 18:34:24 GMT]]></title><description><![CDATA[<p>Nathan schrieb:</p>
<blockquote>
<p>volkard schrieb:</p>
<blockquote>
<p>Nathan schrieb:</p>
<blockquote>
<p>Das ist Absicht.</p>
</blockquote>
<p>Ist es notwendig?</p>
</blockquote>
<p>Ja.<br />
Der unterschiedlich Rückgabewert weil sonst sizeof auf den Rückgabewert nicht funktioniert um die ausgewählte Funktion zu bestimmen und der unterschiedliche Paramter, damit die char-Version wenn man sie mit einem int aufruft, geringere Priorität wegen der Konvertierung nach char hat, als die andere Funktion, die man direkt mit einem int aufrufen kann. Ansonsten hätte man eine Ambiguität.</p>
</blockquote>
<p>Danke, daß Du jetzt neben Arcoth auch mich für einen Vollidionten hältst.<br />
Und jetzt antworte nochmal gescheit, warum Du zweimal int/char vertauscht, mir scheint der Doppeltausch nichts zu bewirken, außer die Lesbarkeit zu senken.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413724</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413724</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 16 Aug 2014 18:34:24 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 18:53:46 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>Nathan schrieb:</p>
<blockquote>
<p>volkard schrieb:</p>
<blockquote>
<p>Nathan schrieb:</p>
<blockquote>
<p>Das ist Absicht.</p>
</blockquote>
<p>Ist es notwendig?</p>
</blockquote>
<p>Ja.<br />
Der unterschiedlich Rückgabewert weil sonst sizeof auf den Rückgabewert nicht funktioniert um die ausgewählte Funktion zu bestimmen und der unterschiedliche Paramter, damit die char-Version wenn man sie mit einem int aufruft, geringere Priorität wegen der Konvertierung nach char hat, als die andere Funktion, die man direkt mit einem int aufrufen kann. Ansonsten hätte man eine Ambiguität.</p>
</blockquote>
<p>Danke, daß Du jetzt neben Arcoth auch mich für einen Vollidionten hältst.</p>
</blockquote>
<p>Äh, moment.<br />
Arcoth halte ich nicht für einen Vollidioten, ich dachte der fehlerhafte Code den Abrakadabra zitiert hatte, stammte von ihm, als ich meinen Beitrag geschrieben habe, da ich den von ihm nur überflogen hatte. Das Arcoth den Fehler gemacht hat, fiel mir nicht auf, weswegen ich meine Antwort halt so formuliert.<br />
Und dich halte ich auch nicht für einen Vollidioten. Ich hatte mich schon gewundert, dass du das gefragt hast*, habs aber normal beantwortet, weil ich dachte, dass du auf etwas hinauswillst, was du ja scheinbar auch wolltest. Ich hatte gerechnet, dass du mich jetzt total bloßstellst, weil ich irgendetwas nicht wusste.</p>
<blockquote>
<p>Und jetzt antworte nochmal gescheit, warum Du zweimal int/char vertauscht, mir scheint der Doppeltausch nichts zu bewirken, außer die Lesbarkeit zu senken.</p>
</blockquote>
<p>Der Code ist von Arcoth, nicht von mir.<br />
Und was meinst du mit &quot;Doppeltausch&quot;?</p>
<p>*Siehe mein Fragezeichen, bevor ich &quot;Das ist Absicht&quot; schrieb.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413728</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413728</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Sat, 16 Aug 2014 18:53:46 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 19:18:58 GMT]]></title><description><![CDATA[<p>Sorry, ambiq formuliert, gemein war &quot;daß nach Arcoth auch Du mich für&quot;.</p>
<p>Nathan schrieb:</p>
<blockquote>
<p>weil ich dachte, dass du auf etwas hinauswillst,</p>
</blockquote>
<p>Mich hat's verwirrt, daß int/char zweimal vertauscht werden und dachte, wenn man das vermeiden würde, müßte man nur noch halb so viel sich im Kopf merken, um zu verstehen, wie der Code geht. Vielleicht bin ich noch nicht richtig wach heute, aber irgendwie scheint mir der &quot;Doppeltausch&quot; ungünstig zu sein.</p>
<pre><code>template&lt;typename T&gt;
class test
{
    template &lt;int&gt;//int rein =&gt; int raus.
    struct Nothing {typedef int type;};

    template &lt;typename U&gt;//int rein =&gt; int raus.
    static typename Nothing&lt;sizeof(&amp;U::operator())&gt;::type check(int);

    template &lt;typename&gt;//char rein =&gt; char raus.
    static char check(char);

public:

    static const bool is_functor = sizeof(check&lt;T&gt;(0)) != 1;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2413731</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413731</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 16 Aug 2014 19:18:58 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 19:25:05 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>Sorry, ambiq formuliert, gemein war &quot;daß nach Arcoth auch Du mich für&quot;.</p>
<p>Nathan schrieb:</p>
<blockquote>
<p>weil ich dachte, dass du auf etwas hinauswillst,</p>
</blockquote>
<p>Mich hat's verwirrt, daß int/char zweimal vertauscht werden und dachte, wenn man das vermeiden würde, müßte man nur noch halb so viel sich im Kopf merken, um zu verstehen, wie der Code geht. Vielleicht bin ich noch nicht richtig wach heute, aber irgendwie scheint mir der &quot;Doppeltausch&quot; ungünstig zu sein.</p>
<pre><code>template&lt;typename T&gt;
class test
{
    template &lt;int&gt;//int rein =&gt; int raus.
    struct Nothing {typedef int type;};

    template &lt;typename U&gt;//int rein =&gt; int raus.
    static typename Nothing&lt;sizeof(&amp;U::operator())&gt;::type check(int);

    template &lt;typename&gt;//char rein =&gt; char raus.
    static char check(char);

public:

    static const bool is_functor = sizeof(check&lt;T&gt;(0)) != 1;
};
</code></pre>
</blockquote>
<p>Ach so, das meinst du. Die int Version sollte auch int nehmen und die char Version char.<br />
Ja, da stimme ich dir zu, ich habe das Problem bei meinem generischem &quot;Ausdruck gültig?&quot; folgendermaßen umgangen:</p>
<pre><code>template &lt;typename T, typename Expr&gt;
class expression_valid
{
    // char und int haben keinerlei semantische Bedeutung und können außerdem noch gleich groß sein
    using matched_t     = char(&amp;)[1];
    using unmatched_t   = char(&amp;)[2];

    template &lt;class T2&gt;
    static matched_t checker(decltype(Expr::template check&lt;T2&gt;())) noexcept;

    // ellipsis als default, das ist aktuell noch der einzig anehmbare Verwendungszweck in C++ und außerdem garantiert das schlechteste Match
    template &lt;class T2&gt;
    static unmatched_t checker(...) noexcept;

public:
    // weitaus mehr Semantik als == 1
    // besser wäre sogar noch is_same, aber gut
    static constexpr auto value = sizeof(checker&lt;T&gt;(0)) == sizeof(matched_t);
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2413733</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413733</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Sat, 16 Aug 2014 19:25:05 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 21:01:10 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/106">@volkard</a> Niemand hält dich für einen Idioten.</p>
<blockquote>
<p>Vielleicht bin ich noch nicht richtig wach heute, aber irgendwie scheint mir der &quot;Doppeltausch&quot; ungünstig zu sein.</p>
</blockquote>
<p>Das ist mir direkt aufgefallen nachdem ich den Code geschrieben habe - die Tatsache dass das irgendjemand benörgeln wird war mir auch sofort bewusst, aber ich war einfach zu faul es zu korrigieren.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/29873">@Nathan</a> Für <code>matched_t</code> &amp; co. etwas benutze ich <a href="https://github.com/Arcoth/VTMPL/blob/master/overload_ranker.hxx" rel="nofollow">das</a> oder ähnliches. Fasst du so etwas nicht zusammen?<br />
Und war es wirklich nötig <code>checker</code> als <code>noexcept</code> zu markieren?</p>
<p>Endlich ist mir bei Nathans Version aufgefallen warum die Rückgabetypen Referenzen sind - wären ja sonst beides Zeiger.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413741</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413741</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sat, 16 Aug 2014 21:01:10 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sat, 16 Aug 2014 21:20:02 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/29873">@Nathan</a> Für <code>matched_t</code> &amp; co. etwas benutze ich <a href="https://github.com/Arcoth/VTMPL/blob/master/overload_ranker.hxx" rel="nofollow">das</a> oder ähnliches. Fasst du so etwas nicht zusammen?</p>
</blockquote>
<p>Ich brauchte zu dem Zeitpunkt nur zwei einfache Typedefs unterschiedlicher Größe, da kam ich gar nicht auf die Idee das zu generalisieren.<br />
Dein rank Ding ist aber nice.</p>
<blockquote>
<p>Und war es wirklich nötig <code>checker</code> als <code>noexcept</code> zu markieren?</p>
</blockquote>
<p>Gewohnheit. Ich war damals (vor 6 Monaten oder so) in der Phase, wo noexcept mein Default für Funktionen war.<br />
Für neueren Code hab ich meine Exceptionspolicies geändert und somit auch mein noexcept. Ich nutz das jetzt nur aus semantischen Gründen, für Funktionen die nie schief gehen können (Ein operator[] ist bspw. nicht noexcept*, selbst wenn er nicht den Index checkt, man kann einen Segfault kriegen, d.h. die Funktion failen).</p>
<blockquote>
<p>Endlich ist mir bei Nathans Version aufgefallen warum die Rückgabetypen Referenzen sind - wären ja sonst beides Zeiger.</p>
</blockquote>
<p>Da hast du mir was voraus. Ich musste beim Copy-Pasten erst einmal ewig überlegen, wieso Referenzen.</p>
<p>*Genau genommen ist der idR ein spezielles NOFAIL, was &quot;geht nur schief, wenn Programmierer dumm ist&quot; bedeutet und je nachdem ob Logikfehler gecheckt werden noexcept oder nicht ist, aber darum gehts hier nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413745</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413745</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Sat, 16 Aug 2014 21:20:02 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sun, 17 Aug 2014 07:39:29 GMT]]></title><description><![CDATA[<blockquote>
<p>Genau genommen ist der idR ein spezielles NOFAIL, was &quot;geht nur schief, wenn Programmierer dumm ist&quot; bedeutet</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="😃"
    /> <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>
<blockquote>
<p>man kann einen Segfault kriegen,</p>
</blockquote>
<p>Du tust da aber entsprechende Assertions rein, richtig?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413770</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413770</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sun, 17 Aug 2014 07:39:29 GMT</pubDate></item><item><title><![CDATA[Reply to functor_traits und lambda_traits on Sun, 17 Aug 2014 08:13:53 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<blockquote>
<p>man kann einen Segfault kriegen,</p>
</blockquote>
<p>Du tust da aber entsprechende Assertions rein, richtig?</p>
</blockquote>
<p>Ja, ich habe ein spezielles CHECK-Makro, das ist quasi wie ein assert, nur mit Priorität (implementation-Fehler muss man jetzt nicht immer überprüfen...) und kann bei Bedarf auch Exceptions werfen. Deswegen ist der NOFAIL, wenn checks deaktiviert sind, also auch noexcept um ggf. die Optimierung zu kriegen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2413774</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2413774</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Sun, 17 Aug 2014 08:13:53 GMT</pubDate></item></channel></rss>