<?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[Bestimmten Code noch kürzer schreiben]]></title><description><![CDATA[<p>Hi! <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /> Ich will das DRY-Prinzip möglichst oft anwenden. Das Problem ist, ich schreibe oft kleine C++-Klassen, bei denen die Initialization-list mir so überflüssig vorkommt.</p>
<p>Diese Klassen sehen etwa so aus:</p>
<pre><code>class Foo
{
	int a, b;

	foo(int a, int b) : a(a), b(b) {}     &lt;--- das hier ist doch nicht DRY
};
</code></pre>
<p>Gefunden habe ich die Möglichkeit, bei der Instanzierung geschweifte statt runder Klammern zu benutzen. Dann moniert GCC aber, dass ich für &quot;auto foo = Foo{1,2}&quot; ebenso eine Initialization-list brauche wie mit runden Klammern. Also ist das kein Weg für mehr DRY.</p>
<p>Und es gibt wohl auch Initialization-lists im Stile einer variadischen Funktion mit &quot;...&quot;. Aber ich habe keine Idee, wie die da helfen könnten.</p>
<p>Weiss jemand, wie ich die Variablennamen nicht zwei mal zusätzlich schreiben bräuchte? Sollten Klassen dieser Art überhaupt nicht erst entstehen? Mache ich grundsätzlich etwas falsch? - abgesehen davon, dass ich hier auf das DRY-Prinzip und damit auf diesen Beitrag verzichten könnte.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/332787/bestimmten-code-noch-kürzer-schreiben</link><generator>RSS for Node</generator><lastBuildDate>Mon, 27 Apr 2026 10:55:35 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/332787.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 22 May 2015 02:09:49 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 02:09:49 GMT]]></title><description><![CDATA[<p>Hi! <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /> Ich will das DRY-Prinzip möglichst oft anwenden. Das Problem ist, ich schreibe oft kleine C++-Klassen, bei denen die Initialization-list mir so überflüssig vorkommt.</p>
<p>Diese Klassen sehen etwa so aus:</p>
<pre><code>class Foo
{
	int a, b;

	foo(int a, int b) : a(a), b(b) {}     &lt;--- das hier ist doch nicht DRY
};
</code></pre>
<p>Gefunden habe ich die Möglichkeit, bei der Instanzierung geschweifte statt runder Klammern zu benutzen. Dann moniert GCC aber, dass ich für &quot;auto foo = Foo{1,2}&quot; ebenso eine Initialization-list brauche wie mit runden Klammern. Also ist das kein Weg für mehr DRY.</p>
<p>Und es gibt wohl auch Initialization-lists im Stile einer variadischen Funktion mit &quot;...&quot;. Aber ich habe keine Idee, wie die da helfen könnten.</p>
<p>Weiss jemand, wie ich die Variablennamen nicht zwei mal zusätzlich schreiben bräuchte? Sollten Klassen dieser Art überhaupt nicht erst entstehen? Mache ich grundsätzlich etwas falsch? - abgesehen davon, dass ich hier auf das DRY-Prinzip und damit auf diesen Beitrag verzichten könnte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454382</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454382</guid><dc:creator><![CDATA[markus2]]></dc:creator><pubDate>Fri, 22 May 2015 02:09:49 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 05:36:32 GMT]]></title><description><![CDATA[<pre><code>class Rechteck
{
	int a, b;
	Rechteck(int a, int b) : a(a), b(b) {}     &lt;--- das hier ist doch nicht DRY?
};
</code></pre>
<pre><code>class Quadrat:public Rechteck
{
	Quadrat(int a) : Rechteck(a,a) {}     &lt;--- DRY?
};
</code></pre>
<pre><code>class Haus
{
	Quadrat dreieck;
	Dreieck quadrat;
	Haus(   //how to do?
};
</code></pre>
<pre><code>class Mitarbeiter
{
    int alter, gehalt;

    Mitarbeiter(alter):alter(alter),gehalt(gehaltsTabelle[alter]){
       assert(alter&lt;30);//mit über 30 kann man eh nix mehr an der tastatur
    }
    //...     &lt;--- das hier ist jetzt mal DRY
};
...
konz::firm::lib::io::FtpSocket::fomm(...){
   ...
   swap(volkard,Mitarbeiter(alter=17,gehalt=1000000000000000000ULL));//DRY joke?
   ...
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2454387</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454387</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Fri, 22 May 2015 05:36:32 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 06:31:36 GMT]]></title><description><![CDATA[<p>Wir wollen eine 1:1-Korrespondenz zwischen bestimmten Variablennamen ausdrücken, ohne diese auszuschreiben? Ich finde ja, in Makrodefinitionen darf man sich auch mal ausnahmsweise wiederholen, da Makros das nicht anders können. Und sie verschwinden ja sowieso in irgendeinem Header, den man nie wieder anguckt. Dann können wir das Problem dank C++11 variadic macros ganz einfach lösen:</p>
<pre><code>#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__,9,8,7,6,5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,N,...) N

#define ONE_TO_ONE_1(X1) X1(X1)
#define ONE_TO_ONE_2(X1,X2) X1(X1), ONE_TO_ONE_1(X2)
#define ONE_TO_ONE_3(X1,X2,X3) X1(X1), ONE_TO_ONE_2(X2,X3)
#define ONE_TO_ONE_4(X1,X2,X3,X4) X1(X1), ONE_TO_ONE_3(X2,X3,X4)
#define ONE_TO_ONE_5(X1,X2,X3,X4,X5) X1(X1), ONE_TO_ONE_4(X2,X3,X4,X5)
#define ONE_TO_ONE_6(X1,X2,X3,X4,X5,X6) X1(X1), ONE_TO_ONE_5(X2,X3,X4,X5,X6)
#define ONE_TO_ONE_7(X1,X2,X3,X4,X5,X6,X7) X1(X1), ONE_TO_ONE_6(X2,X3,X4,X5,X6,X7)
#define ONE_TO_ONE_8(X1,X2,X3,X4,X5,X6,X7,X8) X1(X1), ONE_TO_ONE_7(X2,X3,X4,X5,X6,X7,X8)
#define ONE_TO_ONE_9(X1,X2,X3,X4,X5,X6,X7,X8,X9) X1(X1), ONE_TO_ONE_8(X2,X3,X4,X5,X6,X7,X8,X9)
// Ich spare mir mal mehr als 9 Argumente. Wer will, mag dies erweitern bis er an die Grenze seines Präprozessors stößt

#define ONE_TO_ONE_IMPL_LEVEL2(N,...) ONE_TO_ONE_ ## N(__VA_ARGS__)
#define ONE_TO_ONE_IMPL(N,...) ONE_TO_ONE_IMPL_LEVEL2(N,__VA_ARGS__)
#define ONE_TO_ONE(...) ONE_TO_ONE_IMPL(VA_NUM_ARGS(__VA_ARGS__),__VA_ARGS__)

class Foo
{
    int a, b; 
    foo(int a, int b) : ONE_TO_ONE(a,b) {}   // Expandiert zu &quot;a(a), b(b)&quot;
};
</code></pre>
<p>Da! Viel kürzer und besser!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454389</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454389</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 22 May 2015 06:31:36 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 07:16:03 GMT]]></title><description><![CDATA[<pre><code>std::tuple&lt;int, int&gt; t;

Foo(decltype(t) const&amp; t) : t(t) {}
</code></pre>
<p>Scheiße, jetzt hab' ich <code>t</code> vielleicht zu oft geschrieben! <em>Kopfschuss</em></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454394</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454394</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Fri, 22 May 2015 07:16:03 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 12:55:54 GMT]]></title><description><![CDATA[<p>Ok, war mir nur nicht sicher, ob ich hier etwas total Einfaches nicht kenne. &quot;takes: int a, b;&quot; oder irgendsowas. Offensichtlich ist das nicht der Fall.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454431</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454431</guid><dc:creator><![CDATA[markus2]]></dc:creator><pubDate>Fri, 22 May 2015 12:55:54 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 16:47:30 GMT]]></title><description><![CDATA[<p>Also ich fände es schon praktisch wenn man einige solche Sachen defaulten könnte... Gerade bei Copy-Construktor oder Asignment Zeug ist es sehr nervig wenn man neue Member zu der Klasse hinzufügen will, weil man dann alle Copy-, Asignment- und Move Dinger auch anpassen muss (und nicht mal nen Fehler bekommt wenn mans vergisst).</p>
<p>Sowas wäre cool:</p>
<pre><code>struct foo
{
    std::atomic&lt;bool&gt; b;
    int i, j;

    foo (int i, int j) : i(i), j(j), b(false) {}
    foo (foo const &amp;f) : b(f.b.load()), default {} // Alle restlichen Member default-kopiert
    foo &amp;operator=(foo const &amp;f)
    {
        if (this != &amp;f)
        {
            b = f.b.load();
            default; // Syntax ist natürlich Verbesserungsfähig^^
        }
        return *this;
    }
    // ...
};
</code></pre>
<p>Denn obwohl mir das schon oft passiert ist vergesse ich es immer noch regelmäßig <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454460</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454460</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Fri, 22 May 2015 16:47:30 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 17:08:23 GMT]]></title><description><![CDATA[<p>das Angesprochene Feature von euch beiden ist viel zu eingeschränkt und sonst nirgends sauber verwendbar das man es deswegen ausgelassen hat</p>
<p>zum copy ctor</p>
<p><a href="http://stackoverflow.com/questions/276173/what-are-your-favorite-c-coding-style-idioms/2034447#2034447" rel="nofollow">http://stackoverflow.com/questions/276173/what-are-your-favorite-c-coding-style-idioms/2034447#2034447</a></p>
<p>genau so wie bei const doppelt implementieren</p>
<p><a href="http://stackoverflow.com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-func" rel="nofollow">http://stackoverflow.com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-func</a></p>
<p>usw. usw.....</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454462</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454462</guid><dc:creator><![CDATA[Gast3]]></dc:creator><pubDate>Fri, 22 May 2015 17:08:23 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 18:03:12 GMT]]></title><description><![CDATA[<p>*&quot;Es löst ein Problem, aber es löst nicht alle anderen =&gt; wir warten lieder auf die perfekte Lösung für alles auf einmal (die es nie geben wird)&quot;<br />
*<br />
Ich fand diese Einstellung/Argumentation schon immer sehr [euphemismus]befremdlich[/euphemismus].<br />
Ist das perfekte Totschlagargument um jeglichen Fortschritt zu verhindern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454465</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454465</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 22 May 2015 18:03:12 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Sat, 23 May 2015 09:44:20 GMT]]></title><description><![CDATA[<p>Eine allgemeine Syntax könnte etwa so aussehen:</p>
<pre><code class="language-cpp">struct Rechteck
{
    int a, b;

	constexpr auto members = std::reflect&lt;Rechteck&gt;::public_members;
    Rechteck(members::type $&lt;members::name&gt;...) : $&lt;members::name&gt;($&lt;members::name&gt;)...
	{
	}
};
</code></pre>
<p>Das sind drei neue Sprach-Features:</p>
<ul>
<li>Operator ... zum Expandieren von <code>constexpr</code> -Ranges (geht heute nur mit variadic templates)</li>
<li>das Expandieren mit ... in eine Initialisierungsliste</li>
<li><code>constexpr</code> -Zeichenketten als Bezeichner. Da ist mir auf die Schnelle nichts besseres eingefallen als <code>$&lt;&gt;</code></li>
</ul>
<p>Ein viertes Feature macht solche Konstruktoren wiederverwendbar:</p>
<pre><code class="language-cpp">template &lt;
	class Class,
	auto members = std::reflect&lt;Class&gt;::public_members
&gt;
this construct_members(members::type $&lt;members::name&gt;...)
	: $&lt;members::name&gt;($&lt;members::name&gt;)...
{
}

struct Rechteck
{
    int a, b;
	using construct_members&lt;Rechteck&gt;;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2454469</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454469</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Sat, 23 May 2015 09:44:20 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 19:05:46 GMT]]></title><description><![CDATA[<blockquote>
<p>das Expandieren mit ... in eine Initialisierungsliste</p>
</blockquote>
<p>Inwiefern ist das neu?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454470</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454470</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Fri, 22 May 2015 19:05:46 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 22:13:31 GMT]]></title><description><![CDATA[<p>markus2 schrieb:</p>
<blockquote>
<p>Weiss jemand, wie ich die Variablennamen nicht zwei mal zusätzlich schreiben bräuchte?</p>
</blockquote>
<p>ja, klar:</p>
<pre><code>typedef unsigned u;
typedef u short u_s;

inline u combine(u_s ah, u_s al){ return (1 &lt;&lt; 8*sizeof(u_s)) * ah + al; }

struct Foo
{
  u long a;                                   // &lt;- nur noch eine
  Foo(u_s ah, u_s al) : a(combine(ah, al)){}
};

main()
{
  assert(sizeof(u) == 2 * sizeof(u_s));
  Foo f(0x8765, 0x7fff);
  cout &lt;&lt; hex &lt;&lt; f.a &lt;&lt; endl;
}
</code></pre>
<p>- wer schafft's mit null Variablen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454473</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454473</guid><dc:creator><![CDATA[großbuchstaben]]></dc:creator><pubDate>Fri, 22 May 2015 22:13:31 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 23:01:19 GMT]]></title><description><![CDATA[<p>haha</p>
<pre><code>typedef u unsigned
</code></pre>
<p>nice <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454474</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454474</guid><dc:creator><![CDATA[JulianH]]></dc:creator><pubDate>Fri, 22 May 2015 23:01:19 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 23:20:18 GMT]]></title><description><![CDATA[<pre><code>typedef unsigned u; 
  u long a;
</code></pre>
<p>Das ist Unsinn.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454475</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454475</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Fri, 22 May 2015 23:20:18 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 23:25:18 GMT]]></title><description><![CDATA[<p>großbuchstaben schrieb:</p>
<blockquote>
<p>- wer schafft's mit null Variablen?</p>
</blockquote>
<p>Ich bin ja immer noch ein Fan von Makros zwecks Metaprogrammierung:</p>
<pre><code>#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__,9,8,7,6,5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,N,...) N

#define ONE_TO_ONE_1(X1) X1(X1)
#define ONE_TO_ONE_2(X1,X2) X1(X1), ONE_TO_ONE_1(X2)
#define ONE_TO_ONE_3(X1,X2,X3) X1(X1), ONE_TO_ONE_2(X2,X3)
#define ONE_TO_ONE_4(X1,X2,X3,X4) X1(X1), ONE_TO_ONE_3(X2,X3,X4)
#define ONE_TO_ONE_5(X1,X2,X3,X4,X5) X1(X1), ONE_TO_ONE_4(X2,X3,X4,X5)
#define ONE_TO_ONE_6(X1,X2,X3,X4,X5,X6) X1(X1), ONE_TO_ONE_5(X2,X3,X4,X5,X6)
#define ONE_TO_ONE_7(X1,X2,X3,X4,X5,X6,X7) X1(X1), ONE_TO_ONE_6(X2,X3,X4,X5,X6,X7)
#define ONE_TO_ONE_8(X1,X2,X3,X4,X5,X6,X7,X8) X1(X1), ONE_TO_ONE_7(X2,X3,X4,X5,X6,X7,X8)
#define ONE_TO_ONE_9(X1,X2,X3,X4,X5,X6,X7,X8,X9) X1(X1), ONE_TO_ONE_8(X2,X3,X4,X5,X6,X7,X8,X9)

#define ONE_TO_ONE_IMPL_LEVEL2(N,...) ONE_TO_ONE_ ## N(__VA_ARGS__)
#define ONE_TO_ONE_IMPL(N,...) ONE_TO_ONE_IMPL_LEVEL2(N,__VA_ARGS__)
#define ONE_TO_ONE(...) ONE_TO_ONE_IMPL(VA_NUM_ARGS(__VA_ARGS__),__VA_ARGS__)

#define REMOVE_TYPES_2(X1,X2) X2
#define REMOVE_TYPES_4(X1,X2,X3,X4) X2,REMOVE_TYPES_2(X3,X4)
#define REMOVE_TYPES_6(X1,X2,X3,X4,X5,X6) X2,REMOVE_TYPES_4(X3,X4,X5,X6)
#define REMOVE_TYPES_8(X1,X2,X3,X4,X5,X6,X7,X8) X2,REMOVE_TYPES_6(X3,X4,X5,X6,X7,X8)

#define REMOVE_TYPES_IMPL_LEVEL2(N,...) REMOVE_TYPES_ ## N(__VA_ARGS__)
#define REMOVE_TYPES_IMPL(N,...) REMOVE_TYPES_IMPL_LEVEL2(N,__VA_ARGS__)
#define REMOVE_TYPES(...) REMOVE_TYPES_IMPL(VA_NUM_ARGS(__VA_ARGS__),__VA_ARGS__)

#define PARAMETER_LIST_2(X1,X2) X1 X2
#define PARAMETER_LIST_4(X1,X2,X3,X4) X1 X2,PARAMETER_LIST_2(X3,X4) 
#define PARAMETER_LIST_6(X1,X2,X3,X4,X5,X6) X1 X2,PARAMETER_LIST_4(X3,X4,X5,X6) 
#define PARAMETER_LIST_8(X1,X2,X3,X4,X5,X6,X7,X8) X1 X2,PARAMETER_LIST_6(X3,X4,X5,X6,X7,X8) 

#define PARAMETER_LIST_IMPL_LEVEL2(N,...) PARAMETER_LIST_ ## N(__VA_ARGS__)
#define PARAMETER_LIST_IMPL(N,...) PARAMETER_LIST_IMPL_LEVEL2(N,__VA_ARGS__)
#define PARAMETER_LIST(...) PARAMETER_LIST_IMPL(VA_NUM_ARGS(__VA_ARGS__),__VA_ARGS__)

#define REMOVE_COMMAS_ADD_SEMICOLONS_2(X1,X2) X1 X2;
#define REMOVE_COMMAS_ADD_SEMICOLONS_4(X1,X2,X3,X4) X1 X2;REMOVE_COMMAS_ADD_SEMICOLONS_2(X3,X4) 
#define REMOVE_COMMAS_ADD_SEMICOLONS_6(X1,X2,X3,X4,X5,X6) X1 X2;REMOVE_COMMAS_ADD_SEMICOLONS_4(X3,X4,X5,X6) 
#define REMOVE_COMMAS_ADD_SEMICOLONS_8(X1,X2,X3,X4,X5,X6,X7,X8) X1 X2;REMOVE_COMMAS_ADD_SEMICOLONS_6(X3,X4,X5,X6,X7,X8) 

#define REMOVE_COMMAS_ADD_SEMICOLONS_IMPL_LEVEL2(N,...) REMOVE_COMMAS_ADD_SEMICOLONS_ ## N(__VA_ARGS__)
#define REMOVE_COMMAS_ADD_SEMICOLONS_IMPL(N,...) REMOVE_COMMAS_ADD_SEMICOLONS_IMPL_LEVEL2(N,__VA_ARGS__)
#define REMOVE_COMMAS_ADD_SEMICOLONS(...) REMOVE_COMMAS_ADD_SEMICOLONS_IMPL(VA_NUM_ARGS(__VA_ARGS__),__VA_ARGS__)

#define GENERIC_CLASS_BEGIN(NAME, ...) class NAME { REMOVE_COMMAS_ADD_SEMICOLONS(__VA_ARGS__) public: NAME(PARAMETER_LIST(__VA_ARGS__)) : ONE_TO_ONE(REMOVE_TYPES(__VA_ARGS__)) {}
#define GENERIC_CLASS_END };
</code></pre>
<p>Damit kann man dann schreiben:</p>
<pre><code>GENERIC_CLASS_BEGIN(Foo, int, i, double, d, long, l)
  void my_method();
GENERIC_CLASS_END
</code></pre>
<p>Dies expandiert (nach etwas Formatierung) zu:</p>
<pre><code>class Foo 
{ 
  int i;
  double d;
  long l; 
public: 
  Foo(int i,double d,long l) : i(i), d(d), l(l) {}
  void my_method();
};
</code></pre>
<p>Das offensichtliche Problem ist natürlich, dass die Makros selber nicht mehr DRY sind. Wir haben 3x die gleiche Makrokette mit minimalen Unterschieden und eine weitere Makrokette, die ein ähnlich, aber ein bisschen anders ist als die anderen 3. Leider kann man mit Makros keine anderen Makros metaprogrammieren, wir müssen also zu einem externen Präprozessor greifen. Das <em>kann</em> ein manueller Aufruf des C-Präprozessors sein (Sollte ausreichen) oder aber ein mächtigerer Prozessor, wir M4. Das löst auch das Problem der Beschränkung auf 4 Parameter, das mein Code derzeit hat. Das mache ich jetzt aber nicht mehr vor.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454476</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454476</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 22 May 2015 23:25:18 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Fri, 22 May 2015 23:36:48 GMT]]></title><description><![CDATA[<p>großbuchstaben schrieb:</p>
<blockquote>
<p>- wer schafft's mit null Variablen?</p>
</blockquote>
<p>Argh, Mist!<br />
Ich hatte gedacht dass es neben <code>std::getenv</code> auch ein <code>std::setenv</code> gibt. Gibt's aber dummerweise 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>
<p>Aber wenn wir einfach mal so täten als ob...</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;
#include &lt;cstdlib&gt;
#include &lt;stdlib.h&gt;

#define MEMNAME(name) static_cast&lt;std::stringstream&amp;&gt;(std::stringstream() &lt;&lt; static_cast&lt;void const*&gt;(this) &lt;&lt; &quot;-&quot; &lt;&lt; #name).str().c_str()
#define GETMEM(name) static_cast&lt;decltype(this-&gt;name())&gt;(std::atoll(std::getenv(MEMNAME(name))))
#define SETMEM(name, val) ::_putenv_s(MEMNAME(name), std::to_string(static_cast&lt;long long&gt;(val)).c_str())
#define INITMEM(name) SETMEM(name, name)
#define CLRMEM(name) ::_putenv_s(MEMNAME(name), &quot;&quot;)

struct Foo
{
	Foo(int a, int b) { INITMEM(a); INITMEM(b); }
	~Foo() { CLRMEM(a); CLRMEM(b); }
	int a() { return GETMEM(a); }
	int b() { return GETMEM(b); }
};

int main()
{
	Foo f(0x8765, 0x7fff);
	std::cout &lt;&lt; std::hex &lt;&lt; f.a() &lt;&lt; &quot;, &quot; &lt;&lt; f.b() &lt;&lt; std::endl;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2454477</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454477</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 22 May 2015 23:36:48 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Sat, 23 May 2015 01:29:40 GMT]]></title><description><![CDATA[<p>Meine Vorstellung ging eigentlich in eine sehr simple Richtung.</p>
<p>Wenn die Klasse public: und ohne Konstrukor ist, also praktisch nur eine struct, dann erlaubt mir C++ (GCC mit std=c++11 jedenfalls) diese Verwendung:</p>
<pre><code>struct Foo
{
	int a, b;
}

int main()
{
	Foo{1,2};
}
</code></pre>
<p>Und das wäre vielleicht noch schöner, wenn mir C++ einen &quot;Konstruktor&quot; erlauben würde, der mir (das tut die initialization list ja auch?) einen Block erlaubt, der ausgeführt wird, nachdem der brace initializer das Seine getan hat.</p>
<p>Also das hier verbietet GCC mir ja, wenn ich zB. mit Foo{1,2} instanzieren möchte:</p>
<pre><code>struct Foo
{
	int a, b;
	Foo() { }
}
</code></pre>
<p>Das das nicht erlaubt ist, macht sicherlich Sinn. Aber bei der Menge an möglichen Konstruktoren könnte es ja vielleicht für die Brace-initializer auch einen geben?</p>
<pre><code>struct Foo
{
	int a, b;
	Foo{} { } // man beachte die geschweiften Klammern
}
</code></pre>
<p>Aber gut, ich habe mit C++ die Möglichkeit, eine struct (und in gewissem Maß &quot;kein OOP&quot;) zu verwenden, wo ich möchte. Also sei's drum. Mir sind eben oft Features entgangen, weil ich nicht viel modernen Code lese, und deshalb hatte ich die Frage.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454481</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454481</guid><dc:creator><![CDATA[markus2]]></dc:creator><pubDate>Sat, 23 May 2015 01:29:40 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Sat, 23 May 2015 08:27:56 GMT]]></title><description><![CDATA[<p>happystudent schrieb:</p>
<blockquote>
<p>Also ich fände es schon praktisch wenn man einige solche Sachen defaulten könnte... Gerade bei Copy-Construktor oder Asignment Zeug ist es sehr nervig wenn man neue Member zu der Klasse hinzufügen will, weil man dann alle Copy-, Asignment- und Move Dinger auch anpassen muss (und nicht mal nen Fehler bekommt wenn mans vergisst).</p>
<p>Sowas wäre cool:</p>
<pre><code>struct foo
{
    std::atomic&lt;bool&gt; b;
    int i, j;

    foo (int i, int j) : i(i), j(j), b(false) {}
    foo (foo const &amp;f) : b(f.b.load()), default {} // Alle restlichen Member default-kopiert
    foo &amp;operator=(foo const &amp;f)
    {
        if (this != &amp;f)
        {
            b = f.b.load();
            default; // Syntax ist natürlich Verbesserungsfähig^^
        }
        return *this;
    }
    // ...
};
</code></pre>
<p>Denn obwohl mir das schon oft passiert ist vergesse ich es immer noch regelmäßig <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
</blockquote>
<p>Du hast da nicht zu wenig default, sondern zu viel default.<br />
Mach die Defaultkonstruktoren weg.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2454490</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454490</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sat, 23 May 2015 08:27:56 GMT</pubDate></item><item><title><![CDATA[Reply to Bestimmten Code noch kürzer schreiben on Sat, 23 May 2015 09:34:54 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>Du hast da nicht zu wenig default, sondern zu viel default.<br />
Mach die Defaultkonstruktoren weg.</p>
</blockquote>
<p>Hä, was für Defaultkonstruktoren? Da gibts keinen Defaultkonstruktor.</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>Eine allgemeine Syntax könnte etwa so aussehen:</p>
</blockquote>
<p>Oder zB so:</p>
<pre><code>struct foo
{
    int i, j;
    std::atomic&lt;bool&gt; b;

    foo(int i, int j) : b(false), i(i), j(j) {}
    foo(foo const &amp;f) : b(f.b.load()), std::reflect&lt;foo&gt;::members_except(b, std::reflect&lt;foo&gt;::default_init(*this, f) ) {}
    // ...
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2454500</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2454500</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Sat, 23 May 2015 09:34:54 GMT</pubDate></item></channel></rss>