<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>C++ Archives - Creatronix</title>
	<atom:link href="https://creatronix.de/category/software-engineering/cplusplus/feed/" rel="self" type="application/rss+xml" />
	<link>https://creatronix.de/category/software-engineering/cplusplus/</link>
	<description>My adventures in code &#38; business</description>
	<lastBuildDate>Fri, 27 Feb 2026 11:05:54 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>So verwendest Du den std::vector &#8211; Modernes C++</title>
		<link>https://creatronix.de/std-vector-modern-cpp/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Tue, 06 Jan 2026 15:18:25 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7817</guid>

					<description><![CDATA[<p>Motivation Auf meiner Lernreise in die Welt der Robotik ist eines meiner Ziele, mein angestaubtes C++-Wissen aufzubessern. Heute schauen wir uns den std::vector an. Der std::vector ist ein praktisches Hilfsmittel, um in C++ Daten zu verwalten. Man kann ihn mit der Liste in Python vergleichen. Im Gegensatz zum std::array ist der std::vector eine dynamische Datenstruktur,&#8230;</p>
<p>The post <a href="https://creatronix.de/std-vector-modern-cpp/">So verwendest Du den std::vector &#8211; Modernes C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Auf meiner Lernreise in die Welt der Robotik ist eines meiner Ziele, mein angestaubtes C++-Wissen aufzubessern.<br />
Heute schauen wir uns den std::vector an. Der std::vector ist ein praktisches Hilfsmittel, um in C++ Daten zu verwalten.<br />
Man kann ihn mit der Liste in Python vergleichen. Im Gegensatz zum std::array ist der std::vector eine dynamische Datenstruktur, die wächst, wenn neue Werte hinzugefügt werden und die bisherige Kapazität nicht mehr ausreicht.</p>
<h2>Historie</h2>
<p>Den std::vector gibt es bereits ab C++98, er wurde von <a href="https://de.wikipedia.org/wiki/Alexander_Alexandrowitsch_Stepanow_(Informatiker)">Alexander Stepanov</a> entwickelt. Seit C++11 sind einige interessante Neuerungen hinzugekommen.</p>
<h2>Include</h2>
<p>Um einen Vector zu benutzen, wird der Header vector eingebunden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>#include &lt;vector&gt;<vector>
</vector></code></pre>
</div>
<h2>Deklaration</h2>
<p>Der std::vector ist eine Template-Datenstruktur, d.h. wir müssen ihn mit dem Datentyp parametrieren, der eingefügt werden soll:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(VectorTest, VectorInitialSize) {
    const std::vector<int> int_vector;
    EXPECT_EQ(int_vector.capacity(), 0);
    EXPECT_EQ(int_vector.size(), 0);
    EXPECT_EQ(int_vector.empty(), true);
}
</int></code></pre>
</div>
<p>Die Kapazität und die Größe sind am Anfang 0; empty() gibt true zurück</p>
<h2>Daten einfügen</h2>
<p>Die einfachste Art, Daten in den Vector zu packen, ist die push_back()-Methode. Sie hängt ein neues Element an das Ende des vectors</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(VectorTest, VectorPushBack) {
    std::vector<int> int_vector;
    int_vector.push_back(1);
    int_vector.push_back(2);
    int_vector.push_back(3);
    EXPECT_EQ(int_vector.size(), 3);
}
</int></code></pre>
</div>
<p>Mit der Insert-Methode kann an einer beliebigen Stelle im Vector ein Element eingefügt werden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(VectorTest, VectorElementInsert) {
    std::vector<int> int_vector = {1,2,3};
    int_vector.insert(int_vector.begin(), 0);
    EXPECT_EQ(int_vector.at(0), 0);
}
</int></code></pre>
</div>
<p>Allerdings werden dann Elemente um jeweils eine Stelle verschoben (kopiert) was zur Laufzeit in O(n) führt, also O(n²).<br />
Bei vielen Elementen kann es sich lohnen push_back + std::sort zu verwenden, das ist dann in O(n log n)<br />
Zu beachten ist hier zudem, dass die Stelle an der eingefügt werden soll, nicht durch einen Index, sondern durch einen Iterator angegeben wird.</p>
<h2>Daten auslesen</h2>
<p>Grundsätzlich unterstützt vector sowohl den Index-Operator als auch die at()-Methode:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(VectorTest, VectorGetElement) {
    const std::vector<int> int_vector = {1,2,3,4,5};
    EXPECT_EQ(int_vector[2], 3);
    EXPECT_EQ(int_vector.at(2), 3);
}
</int></code></pre>
</div>
<p>Die at()-Methode ist zu bevorzugen, weil sie eine Exception wirft, wenn der Index nicht verfügbar ist.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>
TEST(VectorTest, VectorGetElementException) {
    const std::vector<int> int_vector = {1,2,3,4,5};
    EXPECT_THROW((void)int_vector.at(10), std::out_of_range);
}
</int></code></pre>
</div>
<p>Wenn man am ersten Element im Vektor interessiert ist, kann die front()-Methode benutzt werden. Das letzte Element kann mit back() abgefragt werden.<br />
Aber Vorsicht: auch hier solltest du prüfen, ob der vector nicht leer ist.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(VectorTest, VectorElementBackFront) {
    const std::vector<int> int_vector = {1,2,3};
    if (!int_vector.empty())
    {
        EXPECT_EQ(int_vector.front(), 1);
        EXPECT_EQ(int_vector.back(), 3);
    }
}
</int></code></pre>
</div>
<h2>Daten löschen</h2>
<p>Mit der Methode pop_back() löschst du das letzte Element aus einem Vektor.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>
TEST(VectorTest, VectorElementPopBack) {
    std::vector int_vector = {1,2,3};
    int_vector.pop_back();
    EXPECT_EQ(int_vector.size(), 2);
}</code></pre>
</div>
<p><int>Mit der Methode clear() kann der komplette Vektor geleert werden. Die Size ist danach auch wieder = bzw. empty wieder true</int><int></int></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(VectorTest, VectorClear) {
    std::vector int_vector = {1,2,3};
    int_vector.clear();
    EXPECT_EQ(int_vector.size(), 0);
}</code></pre>
</div>
<p>&nbsp;</p>
<h2>Kapazität vs Größe</h2>
<p>Die Kapazität ist die maximal mögliche Anzahl von Elementen, die Größe die wirkliche Anzahl.<br />
Je nach Compiler wird der Vector unterschiedlich vergrößert:<br />
Clang und der GCC verdoppeln die Größe eines Vectors, sobald die Kapazität nicht mehr ausreicht, um ein weiteres Element einzufügen.</p>
<p><img fetchpriority="high" decoding="async" src="https://creatronix.de/wp-content/uploads/2026/01/vector-capacity-gcc.png" alt="" width="511" height="319" class="alignnone size-full wp-image-7815" srcset="https://creatronix.de/wp-content/uploads/2026/01/vector-capacity-gcc.png 511w, https://creatronix.de/wp-content/uploads/2026/01/vector-capacity-gcc-300x187.png 300w" sizes="(max-width: 511px) 100vw, 511px" /><br />
MSVC erhöht die Kapazität um lediglich 50 %.</p>
<p><img decoding="async" src="https://creatronix.de/wp-content/uploads/2026/01/vector-capacity-msvc.png" alt="" width="423" height="362" class="alignnone size-full wp-image-7814" srcset="https://creatronix.de/wp-content/uploads/2026/01/vector-capacity-msvc.png 423w, https://creatronix.de/wp-content/uploads/2026/01/vector-capacity-msvc-300x257.png 300w" sizes="(max-width: 423px) 100vw, 423px" /></p>
<p>Das Verhalten kann mit folgendem Code überprüft werden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(VectorTest, VectorPushBack) {
    std::vector<int> int_vector;
    int_vector.push_back(1);
    int_vector.push_back(2);
    int_vector.push_back(3);
    EXPECT_EQ(int_vector.size(), 3);

#if defined(_MSC_VER)
    EXPECT_EQ(int_vector.capacity(), 3);
#elif defined(__clang__) || defined(__GNUC__)
    EXPECT_EQ(int_vector.capacity(), 4);
#endif

    int_vector.push_back(4);
    EXPECT_EQ(int_vector.size(), 4);
    EXPECT_EQ(int_vector.capacity(), 4);

    int_vector.push_back(5);
    EXPECT_EQ(int_vector.size(), 5);

#if defined(_MSC_VER)
    EXPECT_EQ(int_vector.capacity(), 6);
#elif defined(__clang__) || defined(__GNUC__)
    EXPECT_EQ(int_vector.capacity(), 8);
#endif

}
</int></code></pre>
</div>
<p>Beide Strategien haben Vor- und Nachteile</p>
<p>Wenn du lieber von vornherein eine explizite Größe vorgeben möchtest, kannst du die reserve()-Funktion benutzen. Dann wird im Vector für die konkrete Kapazität Speicher allokiert.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(VectorTest, VectorReserve) {
    std::vector int_vector;
    int_vector.reserve(100);
    EXPECT_EQ(int_vector.capacity(), 100);
}</code></pre>
</div>
<h2>emplace_back</h2>
<p>Jetzt wird es spannend. Wir haben bisher das push_back auf einfache Datentypen angewendet.<br />
Was passiert aber, wenn wir Objekte in den Vector pushen?</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>std::vector<std::string> str_vector;
str_vector.push_back("Hello world");
</std::string></code></pre>
</div>
<p>Hier wird der string erst erzeugt und dann nochmal kopiert. Das ist natürlich ineffizient, weil das initiale Objekt außerhalb des Funktions-Aufrufes nicht verwendet wird. Deshalb sparen wir uns seit C++11 die Kopie, indem wir emplace_back() verwenden.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(VectorTest, VectorEmplaceBackString) {
    std::vector<std::string> my_vector;
    my_vector.emplace_back("Hello");
    my_vector.emplace_back("World");
    EXPECT_EQ(my_vector.at(0), "Hello");
}
</std::string></code></pre>
</div>
<h2>Quellcode</h2>
<p><a href="https://github.com/jboegeholz/modern_cpp/blob/master/tests/04_test_vector.cpp">https://github.com/jboegeholz/modern_cpp/blob/master/tests/04_test_vector.cpp</a></p>
<h2>Further Reading</h2>
<p>Electronic Arts hat ihre STL-Implementierung geopensourct<br />
<a href="https://github.com/electronicarts/EASTL/blob/master/include/EASTL/vector.h">https://github.com/electronicarts/EASTL/blob/master/include/EASTL/vector.h</a></p>
<p>The post <a href="https://creatronix.de/std-vector-modern-cpp/">So verwendest Du den std::vector &#8211; Modernes C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>So verwendest du std::array &#8211; Modernes C++</title>
		<link>https://creatronix.de/std-array-modern-c-plus-plus/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Wed, 31 Dec 2025 13:30:29 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7777</guid>

					<description><![CDATA[<p>Motivation Auf meiner Lernreise in die Welt der Robotik ist eines meiner Ziele, mein angestaubtes C++-Wissen aufzubessern. Heute schauen wir uns das Konzept von std::array an. Wie war es früher? Vor C++11 musste man C-Style-Arrays benutzen: TEST(ArrayTest, CStyleArray) { int my_int_array[3] = {1, 2, 3}; EXPECT_EQ(my_int_array[0], 1); EXPECT_EQ(my_int_array[1], 2); EXPECT_EQ(my_int_array[2], 3); } Das hat natürlich&#8230;</p>
<p>The post <a href="https://creatronix.de/std-array-modern-c-plus-plus/">So verwendest du std::array &#8211; Modernes C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Auf meiner Lernreise in die Welt der Robotik ist eines meiner Ziele, mein angestaubtes C++-Wissen aufzubessern.<br />
Heute schauen wir uns das Konzept von std::array an.</p>
<h2>Wie war es früher?</h2>
<p>Vor C++11 musste man C-Style-Arrays benutzen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(ArrayTest, CStyleArray) {
    int my_int_array[3] = {1, 2, 3};
    EXPECT_EQ(my_int_array[0], 1);
    EXPECT_EQ(my_int_array[1], 2);
    EXPECT_EQ(my_int_array[2], 3);
}
</code></pre>
</div>
<p>Das hat natürlich ein paar Nachteile:</p>
<h3>Sizeof kompliziert</h3>
<p>Die Funktion sizeof() kann eigentlich nicht direkt für Arrays verwendet werden, da sie die Größe einer Datenstruktur in Bytes angibt.<br />
Das können wir in folgendem Beispiel sehen. Ein Int-Array der Größe drei ist 12 Byte groß ein.<br />
Ein Double-Array der Größe drei hat 24 Byte.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(ArrayTest, CStyleArraySize) {
    int my_int_array[3];
    double my_double_array[3];
    EXPECT_EQ(sizeof(my_int_array), 12);
    EXPECT_EQ(sizeof(my_double_array), 24);
}
</code></pre>
</div>
<p>Deswegen musste man das Ergebnis von sizeof des Arrays noch mal durch die Größe des Datentyp teilen.</p>
<h3>Decaying</h3>
<p>Pointer Decay ist ein weiteres Problem von C-Style-Arrays.</p>
<p>In diesem Beispiel sehen wir, dass ein paar Zeiger an eine Funktion übergeben ist, Array nur noch durch den Zeiger repräsentiert wird.<br />
Sizeof von diesem Datentyp ist normalerweise acht, weil es sich um einen 64 Bit Zeiger handelt.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>int get_size(const int *arr)
{
    return sizeof(arr);
}
TEST(ArrayTest, CStyleArrayPointerDecay) {
    int my_int_array[3];
    EXPECT_EQ(sizeof(my_int_array), 12);
    EXPECT_EQ(get_size(my_int_array), 8); // decays to 64bit pointer
}</code></pre>
</div>
<h3>Unsicherer Indexzugriff</h3>
<p>Auch der Zugriff auf die Daten wie Index Operator ist nicht ungefährlich, weil nicht überprüft wird, ob es sich um einen gültigen Index handelt.</p>
<p>D.h. es fliegt keine Exception sondern das Programm stürzt normalerweise ab.<br />
Wenn man folgenden Code ausführt:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(ArrayTest, CStyleArrayIndex) {
    int my_int_array[3] = {1, 2, 3};
    my_int_array[4] = 1;
    EXPECT_EQ(my_int_array[4], 1);
}
</code></pre>
</div>
<p>Bekommt man:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>Process finished with exit code 134 (interrupted by signal 6:SIGABRT)</code></pre>
</div>
<h2>std::array &#8211; modernes C++</h2>
<p>Jetzt wollen wir uns mal anschauen, wie das std::array funktioniert.</p>
<p>Seit C++11 kann man den header &lt;array&gt; <array>inkludieren und bekommt die Möglichkeit, ein array zu definieren,<br />
dass dem C-Style-Array recht ähnlich sieht. Auch der Zugriff auf die Elemente mit dem Index Operator ist identisch:</array></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(ArrayTest, StdArray) {
    std::array&lt;int, 3&gt; my_std_array = {1, 2, 3};

    EXPECT_EQ(my_std_array[0], 1);
    EXPECT_EQ(my_std_array[1], 2);
    EXPECT_EQ(my_std_array[2], 3);

}
</code></pre>
</div>
<h2>Was macht std::array besser?</h2>
<h3>size()-Funktion</h3>
<p>std::array besitzt eine size()-Methode, die die korrekte Größe des Arrays ausgibt:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(ArrayTest, StdArraySize) {
    std::array&lt;int, 3&gt; my_int_array{};
    std::array&lt;int64_t, 3&gt; my_int_64_array{};
    EXPECT_EQ(my_int_array.size(), 3);
    EXPECT_EQ(my_int_64_array.size(), 3);
}
</code></pre>
</div>
<h3>at()-Funktion</h3>
<p>Die at()-Methode greift wie der Index-Operator auf das n-te Element zu:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(ArrayTest, StdArrayAt) {
    std::array&lt;int, 3&gt; my_std_array = {1, 2, 3};

    EXPECT_EQ(my_std_array.at(0), 1);
    EXPECT_EQ(my_std_array.at(1), 2);
    EXPECT_EQ(my_std_array.at(2), 3);
}
</code></pre>
</div>
<p>Auch das Setzen der Elemente geht über die at()-Methode:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(ArrayTest, AddElementsToArrayWithAt) {
    std::array&lt;int, 3&gt; my_array{};
    my_array.at(0) = 1;
    my_array.at(1) = 2;
    my_array.at(2) = 3;
    EXPECT_EQ(my_array[0], 1);
    EXPECT_EQ(my_array[1], 2);
    EXPECT_EQ(my_array[2], 3);
}
</code></pre>
</div>
<p>Gut ist, dass sie eine Exception wirft, wenn der Zugriff außerhalb des Arrays erfolgt:<br />
Die Exception kann dann über ein try/catch zur Laufzeit gefangen werden.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(ArrayTest, ArrayTestCatchException) {
    std::array&lt;int, 4&gt; my_std_array = {8, 7, 6, 5};

    try
    {
        std::cout &lt;&lt; "Element at postion 4: " &lt;&lt; my_std_array.at(4) &lt;&lt; std::endl;
    }
    catch (const std::out_of_range&amp; ex)
    {
        std::cerr &lt;&lt; ex.what() &lt;&lt; '\n';
        EXPECT_NE(ex.what(), nullptr);
    }
}
</code></pre>
</div>
<h3>Arrays als Funktionsparameter</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>void power2(std::span<int> arr)
{
    for (int &amp; i : arr) {
        i *= 2;
    }
}
TEST(ArrayTest, StdArrayFunctionCall) {
    std::array&lt;int, 4&gt; my_std_array = {8, 7, 6, 5};
    power2(my_std_array);
    EXPECT_EQ(my_std_array[0], 16);
}
</int></code></pre>
</div>
<h3>sort</h3>
<p>Da sich ein std::array wie ein normaler STL-Container verhält, lässt sich das array mit std::sort sortieren:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(ArrayTest, StdArraySort) {
    std::array&lt;int, 4&gt; my_std_array = {8, 7, 6, 5};
    std::sort(my_std_array.begin(), my_std_array.end());
    EXPECT_EQ(my_std_array[0], 5);
}
</code></pre>
</div>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(ArrayTest, StdArraySortWithRanges) {
    std::array&lt;int, 4&gt; my_std_array = {8, 7, 6, 5};
    std::ranges::sort(my_std_array);
    EXPECT_EQ(my_std_array[0], 5);
}
</code></pre>
</div>
<h2>Beispiel aus der Robotik</h2>
<p><a href="https://github.com/jboegeholz/udemy_ros2_for_beginners/blob/3c082c605043155b7f617471a50bc3dbf3fa9929/src/my_cpp_pkg/src/led_panel_server.cpp#L47">https://github.com/jboegeholz/udemy_ros2_for_beginners/blob/3c082c605043155b7f617471a50bc3dbf3fa9929/src/my_cpp_pkg/src/led_panel_server.cpp#L47</a></p>
<h2>Kompletter Code</h2>
<p><a href="https://github.com/jboegeholz/modern_cpp/blob/master/tests/02_test_std_array.cpp">https://github.com/jboegeholz/modern_cpp/blob/master/tests/02_test_std_array.cpp</a></p>
<p>The post <a href="https://creatronix.de/std-array-modern-c-plus-plus/">So verwendest du std::array &#8211; Modernes C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>So verwendest du Google Test in deinem C++-Projekt</title>
		<link>https://creatronix.de/so-verwendest-du-google-test-in-deinem-cpp-projekt/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Sun, 28 Dec 2025 14:31:42 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Software Engineering & Programming]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7766</guid>

					<description><![CDATA[<p>Motivation So, auf geht&#8217;s! Test Driven Development für C++ Projekte. Google Test (oft auch als gtest abgekürzt) ist ein Test Framework, das von Google entwickelt wurde. 2008 wurde es als Open Source veröffentlicht, seit 2015 findest du es auf github. Voraussetzungen Um Google Test in deinen Projekten verwenden zu können, musst du CMake installiert haben.&#8230;</p>
<p>The post <a href="https://creatronix.de/so-verwendest-du-google-test-in-deinem-cpp-projekt/">So verwendest du Google Test in deinem C++-Projekt</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>So, auf geht&#8217;s! Test Driven Development für C++ Projekte.</p>
<p>Google Test (oft auch als gtest abgekürzt) ist ein Test Framework, das von Google entwickelt wurde. 2008 wurde es als Open Source veröffentlicht, seit 2015 findest du es auf github.</p>
<h2>Voraussetzungen</h2>
<p>Um Google Test in deinen Projekten verwenden zu können, musst du CMake installiert haben. Zudem empfiehlt es sich, dein Projekt mit git zu versionieren, weil du dann Google Test als git Submodul installieren kannst.</p>
<h2>Installation</h2>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>cd my_project
git submodule add https://github.com/google/googletest.git external/googletest
git submodule update --init --recursive</code></pre>
</div>
<h2>CMake</h2>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="CMake"><code>cmake_minimum_required(VERSION 3.14)
project(my_project)

set(CMAKE_CXX_STANDARD 17)

add_subdirectory(external/googletest)
include(GoogleTest)
enable_testing()

add_executable(google_test_examples tests/00_google_test.cpp)
target_link_libraries(google_test_examples gtest_main)
gtest_discover_tests(google_test_examples)</code></pre>
</div>
<h2>Code</h2>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>#include &lt;gtest/gtest.h&gt;
</code></pre>
</div>
<h3>Standard Vergleiche</h3>
<p>Standardmäßig vergleicht man gerne auf Gleichheit beziehungsweise Ungleichheit.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(GoogleTestExamples, EXPECT_EQ) {
    const int a = 10;
    const int b = 10;
    EXPECT_EQ(a, b);
}

TEST(GoogleTestExamples, EXPECT_NE) {
    const int a = 10;
    const int b = 11;
    EXPECT_NE(a, b);
}
</code></pre>
</div>
<p>Auch bool&#8217;sche Ausdrücke lassen sich vergleichen, auf true oder false. Das wäre aber auch schon mit dem eingebauten Assert direkt in C++ möglich. Deswegen schauen wir uns spannendere Testfälle an:</p>
<h3>Float und double vergleichen</h3>
<div>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(GoogleTestExamples, EXPECT_FLOAT_EQ) {
    const float a = 10.0;
    const float b = 10.000001;
    EXPECT_FLOAT_EQ(a, b);
}</code></pre>
</div>
</div>
<div>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(GoogleTestExamples, EXPECT_DOUBLE_EQ) {
    const float a = 10.0;
    const float b = 10.0000001;
    EXPECT_DOUBLE_EQ(a, b);
}</code></pre>
</div>
</div>
<h3>Exceptions testen</h3>
<p>Schön ist es, dass Google Test auch das Testen von Exceptions unterstützt:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST(GoogleTestExamples, ArrayException) {
    constexpr std::array&lt;int, 3&gt; my_array = {1,2,3};
    EXPECT_THROW((void)my_array.at(10), std::out_of_range);
}
</code></pre>
</div>
<h2>SIGABRT testen</h2>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>void double_unique_ptr() {
    auto * p = new int(10);
    const std::unique_ptr&lt;int&gt; ptr1 {p};
    const std::unique_ptr&lt;int&gt; ptr2 {p};
}
TEST(MyUniquePointer, DoubleUniquePointer) {
    EXPECT_DEATH(double_unique_ptr(), ".*");
}</code></pre>
</div>
<h2>std::out abfangen</h2>
<p>Wenn wir Code schreiben, der auf std::out schreibt, können wir mit <code>CaptureStdout</code>die Ausgabe abfangen:</p>
<div>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>#include &lt;span&gt;
#include &lt;iostream&gt;
#include &lt;gtest/gtest.h&gt;

void print(const std::span&lt;const int&gt; values) {
    for (const int v : values) {
        std::cout &lt;&lt; v &lt;&lt; " ";
    }
}
TEST(SpanTest, StdPrintExtrapolation) {
    testing::internal::CaptureStdout();

    const int arr[] = {1, 2, 3, 4, 5};
    print(arr);

    const std::string output = testing::internal::GetCapturedStdout();
    EXPECT_EQ(output, "1 2 3 4 5 ");
}</code></pre>
</div>
</div>
<h2>Test Fixtures</h2>
<p>Wenn man schon etwas Erfahrung mit dem Erstellen von Tests hat, genießt man Features wie Test Fixtures.</p>
<p>Ein Test Fixture ist eine Methode, wie man für eine Vielzahl von Tests die Startbedingungen festlegen kann. Variablen initialisieren und Objekte instantiieren beispielsweise.</p>
<p>In klassischen Testframeworks wie JUnit oder auch Python Unittest muss man dafür die Setup-Methode der Testklasse verwenden. In modernen Testframeworks wie pytest, sind fixtures freistehende Funktionen.</p>
<p>In Google Test besteht ein Fixture aus einer Klasse die von ::testing::Test erbt und die SetUp()-Methode überschreibt.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>class TestFixture : public ::testing::Test {
protected:
    void SetUp() override {
        speed = 100;
    }

    int speed{};
};
</code></pre>
</div>
<p>Dann können wir mit dem Test-Makro TEST_F das Fixture verwenden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>TEST_F(TestFixture, IncreasesSpeed) {
    speed += 50;
    EXPECT_EQ(speed, 150);
}

TEST_F(TestFixture, DecreasesSpeed) {
    speed -= 30;
    EXPECT_EQ(speed, 70);
}
</code></pre>
</div>
<h2>Parametrisierte Tests</h2>
<p>Parametrisierung Tests sind ein sehr wertvolles Werkzeug, gerade wenn man TDD benutzt, um seine Programme zu schreiben.<br />
Bei the Rule of three führt man normalerweise eine Optimierung durch, sobald man dreimal das Gleiche getan hat.<br />
Oft ist das der Aufruf einer neuen Funktion mit einem dritten Parameter.</p>
<p>Deshalb könnte dann hier ein parametrisierter Test drei Testfälle ersetzen.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>class AbsTest : public ::testing::TestWithParam&lt;std::pair&lt;int, int&gt;&gt; {
    // no setup needed
};

TEST_P(AbsTest, ComputesAbsoluteValue) {
    int input = GetParam().first;
    int expected = GetParam().second;

    EXPECT_EQ(std::abs(input), expected);
}

INSTANTIATE_TEST_SUITE_P(
    AbsValues,
    AbsTest,
    ::testing::Values(
        std::make_pair(-3, 3),
        std::make_pair(-1, 1),
        std::make_pair(0, 0),
        std::make_pair(2, 2)
    )
);
</code></pre>
</div>
<h2>Tests ausführen</h2>
<p>Um die Tests auszuführen, wechseln wir in das Build-Verzeichnis und starten die Tests über ctest:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>cd cmake-build-debug
ctest</code></pre>
</div>
<h2>Test Reports erstellen</h2>
<p>In größeren Projekten wird gerne für die Weiterverarbeitung ein Report in HTML oder XML erwartet,<br />
der sich zum Beispiel für den Import in ein Quality Gate Tool wie Sonar Cube eignet.<br />
In Google Test erreicht man dies, in dem man ctest so ausführt:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ctest --output-junit test-report.xml</code></pre>
</div>
<h2>Übersicht Test Makros</h2>
<table>
<tbody>
<tr>
<td>Assertion</td>
<td>Bedeutung</td>
</tr>
<tr>
<td>EXPECT_EQ(a, b)</td>
<td>a == b</td>
</tr>
<tr>
<td>EXPECT_NE(a, b)</td>
<td>a != b</td>
</tr>
<tr>
<td>EXPECT_LT(a, b)</td>
<td>a &lt; b</td>
</tr>
<tr>
<td>EXPECT_LE(a, b)</td>
<td>a &lt;= b</td>
</tr>
<tr>
<td>EXPECT_GT(a, b)</td>
<td>a &gt; b</td>
</tr>
<tr>
<td>EXPECT_GE(a, b)</td>
<td>a &gt;= b</td>
</tr>
<tr>
<td>EXPECT_TRUE(expr)</td>
<td>Ausdruck ist **true**</td>
</tr>
<tr>
<td>EXPECT_FALSE(expr)</td>
<td>Ausdruck ist **false**</td>
</tr>
<tr>
<td>EXPECT_STREQ(a, b)</td>
<td>zwei const char* sind gleich</td>
</tr>
<tr>
<td>EXPECT_STRNE(a, b)</td>
<td>zwei const char* sind ungleich</td>
</tr>
<tr>
<td>EXPECT_FLOAT_EQ(a, b)</td>
<td>zwei float sind „nahe genug“</td>
</tr>
<tr>
<td>EXPECT_DOUBLE_EQ(a, b)</td>
<td>zwei double sind „nahe genug“</td>
</tr>
</tbody>
</table>
<h2>Fazit</h2>
<p>Google Test ist ein angenehmes Test-Framework mit einer entspannten Lernkurve.<br />
Die Integration in moderne IDEs wie Jetbrains CLion ist ein weiterer Pluspunkt.<br />
Den gesamten Code findest du hier:<a href="https://github.com/jboegeholz/modern_cpp/blob/master/tests/00_google_test.cpp"> https://github.com/jboegeholz/modern_cpp/blob/master/tests/00_google_test.cpp</a></p>
<h2>Weiterführende Links</h2>
<p><a href="https://creatronix.de/software-testing-concepts/">https://creatronix.de/software-testing-concepts/</a><br />
<a href="https://creatronix.de/wie-tdd-die-welt-rettet-und-deine-nerven-schont/">https://creatronix.de/wie-tdd-die-welt-rettet-und-deine-nerven-schont/</a><br />
<a href="https://creatronix.de/wie-baue-ich-eine-entwicklungsbegleitende-software-qualitatssicherung-auf/">https://creatronix.de/wie-baue-ich-eine-entwicklungsbegleitende-software-qualitatssicherung-auf/</a></p>
<p>The post <a href="https://creatronix.de/so-verwendest-du-google-test-in-deinem-cpp-projekt/">So verwendest du Google Test in deinem C++-Projekt</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Modernes C++</title>
		<link>https://creatronix.de/modernes-c-plus-plus/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Sun, 07 Dec 2025 19:44:45 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7715</guid>

					<description><![CDATA[<p>Im Rahmen meiner Robotik-Experimente bin ich wieder in Kontakt mit der Programmiersprache C++ gekommen. Ich habe aktiv als Entwickler von 2005-2009 Komponenten in C++ implementiert. Hatte dann noch mal einen kurzen Kontakt in der Qualitätssicherung aus der Tester-Perspektive mit der Programmiersprache. Wir haben unter anderen JNA-Wrapper für eine C-Library gebaut. Ich hatte immer eine gewisse&#8230;</p>
<p>The post <a href="https://creatronix.de/modernes-c-plus-plus/">Modernes C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Im Rahmen meiner Robotik-Experimente bin ich wieder in Kontakt mit der Programmiersprache C++ gekommen.</p>
<p>Ich habe aktiv als Entwickler von 2005-2009 Komponenten in C++ implementiert. Hatte dann noch mal einen kurzen Kontakt in der Qualitätssicherung aus der Tester-Perspektive mit der Programmiersprache. Wir haben unter anderen JNA-Wrapper für eine C-Library gebaut.</p>
<p>Ich hatte immer eine gewisse Hassliebe zu der Programmiersprache C++. Einerseits, weil ich wusste, dass es für Performance-orientierte Programme zu dem Zeitpunkt nichts besseres gab. Andererseits habe ich gefühlt oft mehr mit dem Compiler gekämpft, als wirklich echte Probleme zu lösen. Das Potenzial sich in den Fuß zu schießen, war enorm.</p>
<p>Die Unterstützung durch moderne IDEs war zu dem Zeitpunkt auch noch schwierig. Obwohl wir mit dem Visual Studio gearbeitet haben, waren viele Dinge so proprietär, dass heutige unverzichtbare Features wie Code Completion oder auch Hinweise von Lintern nicht immer vollumfänglich funktioniert haben.</p>
<p>Allerdings war das alles vor 2011 und seit dem Sprachstandard C++11 sind extrem viele coole Sachen in C++ passiert. Über ein paar Neuerungen habe ich hier geschrieben:</p>
<p><a href="https://creatronix.de/das-auto-keyword-modernes-c-plus-plus/">Das auto keyword</a></p>
<p><a href="https://creatronix.de/std-array-modern-c-plus-plus/">So verwendest du std::array</a></p>
<p><a href="https://creatronix.de/std-vector-modern-cpp/">So verwendest Du den std::vector</a></p>
<p><a href="https://creatronix.de/lambdas-in-cplusplus/">Lambdas in C++</a></p>
<p><a href="https://creatronix.de/c-stdiota-insight-of-the-day/">Container initialisieren mit std::iota</a></p>
<p><a href="https://creatronix.de/modern-cplusplus-how-to-use-tuples/">How to use tuples</a></p>
<p><a href="https://creatronix.de/async/">Funktionen asynchron ausführen</a></p>
<p><a href="https://creatronix.de/multithreading-in-c/">Einführung in Multithreading</a></p>
<p><a href="https://creatronix.de/how-to-use-the-eigen-library-in-cplusplus/">How to use the Eigen library in C++</a></p>
<h2>CMake</h2>
<p><a href="https://creatronix.de/compiler-optionen-fur-sauberes-c/">Compiler-Optionen für sauberes C++</a></p>
<p><a href="https://creatronix.de/wie-setze-ich-die-c-version-in-cmake/">Wie setze ich die C++ Compiler-Version in CMake</a></p>
<h2>Testing</h2>
<p><a href="https://creatronix.de/so-verwendest-du-google-test-in-deinem-cpp-projekt/">So verwendest du Google Test in deinem C++-Projekt</a></p>
<p>&nbsp;</p>
<p>The post <a href="https://creatronix.de/modernes-c-plus-plus/">Modernes C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Lambdas in C++</title>
		<link>https://creatronix.de/lambdas-in-cplusplus/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Thu, 27 Nov 2025 20:07:28 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7697</guid>

					<description><![CDATA[<p>Motivation Auf meiner Lernreise in die Welt der Robotik ist eines meiner Ziele, mein angestaubtes C++-Wissen aufzubessern. Heute schauen wir uns das Konzept von Lambdas an. Beispiel sort Angenommen, wir wollen einen std::vector sortieren, dann können wir das folgendermaßen machen: std::vector&#60;float&#62; numbers = { -3.5, 1.0, -2.0, -11.0}; std::sort(numbers.begin(), numbers.end()); Der Vector wird hier inplace&#8230;</p>
<p>The post <a href="https://creatronix.de/lambdas-in-cplusplus/">Lambdas in C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Auf meiner Lernreise in die Welt der Robotik ist eines meiner Ziele, mein angestaubtes C++-Wissen aufzubessern. Heute schauen wir uns das Konzept von Lambdas an.</p>
<h2>Beispiel sort</h2>
<p>Angenommen, wir wollen einen std::vector sortieren, dann können wir das folgendermaßen machen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>std::vector&lt;float&gt; numbers = { -3.5, 1.0, -2.0, -11.0}; 
std::sort(numbers.begin(), numbers.end());</code></pre>
</div>
<p>Der Vector wird hier inplace aufsteigend sortiert.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>-11.0 &lt; -3.5 &lt; -2.0 &lt; 1.0</code></pre>
</div>
<p>Was aber, wenn wir absteigend sortieren wollen? Bis einschließlich C++03 musste dazu eine Komparator-Funktion definiert werden, die via Funktionszeiger an die sort-Funktion übergeben wird</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>bool sort_descending(const float a, const float b)
{ 
    return a &gt; b; 
} 
std::sort(numbers.begin(), numbers.end(), sort_descending);</code></pre>
</div>
<h3>Nachteile Funktionszeiger</h3>
<p>Diese Funktionen müssen außerhalb der main Funktion und außerhalb von Klassen definiert werden, da nested functions von C++ nicht unterstützt werden und Methoden nicht (einfach) als Funktionszeiger verwendet werden dürfen. &#8220;Externe&#8221; Funktionen können aber nachteilig für die Wartbarkeit einer Code-Basis sein.</p>
<h3>Lambdas for the rescue</h3>
<p>Jetzt kommen die Lambdas ins Spiel. Lambdas sind anonyme Funktionen, die keinen Funktionsnamen besitzen.</p>
<h3>Beispiel mit sort</h3>
<p>Bei einem Lambda-Ausdruck kann der Komparatorcode innerhalb des sort-Funktionsaufrufes definiert werden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>std::sort(numbers.begin(), numbers.end(), [] (const float a, const float b) {return a &gt; b;});</code></pre>
</div>
<h2>Anatomie eines Lambdas</h2>
<p>Hier siehst du den Aufbau eines Lambda-Befehls:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>[capture list](parameter) -&gt; return_type { body }</code></pre>
</div>
<h3>Capture-List</h3>
<p>Die Capture List sagt dem Compiler, welche Variablen aus dem umgebenden Kontext (bspw. lokale Variablen in main) in das Lambda übernommen werden sollen.<br />
Wie wir später sehen werden, ist es oft auch eine gute Idee, den this-Zeiger in der Capture-List einzufangen, da das die Lesbarkeit erhöht.</p>
<h3>Parameter</h3>
<p>Wie bei einer normalen Funktion sind die Parameter die Platzhalter für die Argumente, die an die Funktion übergeben werden sollen und die in der Funktion verwendet werden können.</p>
<h3>Return-Type</h3>
<p>Der Compiler kann in den meisten Fällen den Rückgabetyp des Lambdas herleiten, deswegen muss er nicht immer explizit angegeben werden.</p>
<h3>Funktionsrumpf</h3>
<p>Im Rumpf der Funktion können nun sowohl die gecapturerten Variablen, als auch die Parameter verwendet werden.<br />
Der Return-Wert muss zum return-type passen, falls dieser explizit angegeben wurde.</p>
<h2>Named Generic Lambdas</h2>
<p>Seit C++14 kann ein Lambda-Ausdruck auch einer Variablen zugewiesen werden. Es muss hier das auto keyword verwendet werden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>auto twice = [] (const auto&amp; x) { 
    return 2*x; 
}; </code></pre>
</div>
<p>double ist jetzt ein Lambda-Objekt, das auch innerhalb einer anderen Funktion definiert werden kann.<br />
Aufgerufen wird es nun wie eine herkömmliche Funktion:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>std::cout &lt;&lt; twice(4);</code></pre>
</div>
<h2>std::bind vs lambda</h2>
<p>Zurück zur Robotik.</p>
<p>std:bind ist eine Möglichkeit in C++, Methoden einer Klasse als callback-Funktionen zu verwenden. Dies wird gerne in ROS-Nodes verwendet, um zum Beispiel Timer-Callbacks zu realisieren. Hier ein Beispiel aus dem sehr guten ROS-Tutorial von <a href="https://www.udemy.com/course/ros2-for-beginners/">Eduard Rennard</a>:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>timer = this-&gt;create_wall_timer(std::chrono::milliseconds(1000), std::bind(&amp;RobotNewsStationNode::publish_message, this));
</code></pre>
</div>
<p>Das sieht für das ungeübte Auge etwas krude aus. Das liegt daran, dass Methoden (also Funktionen einer Klasse) keine Function Pointer sein können. Als Alternative können hier auch Lambdas benutzt werden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>timer = this-&gt;create_wall_timer(std::chrono::milliseconds(1000), [this] { publish_message(); });
</code></pre>
</div>
<p>Das wirkt schon deutlich übersichtlicher. Die Capture-List bringt den this-Zeiger in den Scope des Lambdas, deshalb kann im Funktionsrumpf direkt die publish_message Methode aufgerufen werden.</p>
<h3>Lambdas mit Parametern</h3>
<p>Wenn an den Callback auch Parameter übergeben werden sollen, wird es mit std::bind noch unübersichtlicher, weil hier der Platzhalter für Funktionsargumente _1 benutzt werden muss:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>using namespace std::placeholders;
using example_interfaces::msg::String;
subscriber = this-&gt;create_subscription<string>("/talker", 10, std::bind(&amp;MyListener::listener_callback, this, _1));</string></code></pre>
</div>
<p>Auch hier kann ein Lambda-Ausdruck wieder etwas Lesbarkeit zurückbringen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>subscriber = this-&gt;create_subscription<string>("/talker", 10, [this](const String &amp;msg) { listener_callback(msg);});</string></code></pre>
</div>
<p>The post <a href="https://creatronix.de/lambdas-in-cplusplus/">Lambdas in C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Das auto keyword &#8211; Modernes C++</title>
		<link>https://creatronix.de/das-auto-keyword-modernes-c-plus-plus/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Sat, 26 Apr 2025 20:17:26 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Software Engineering & Programming]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7366</guid>

					<description><![CDATA[<p>Motivation Wenn man lange mit dynamisch typisierten Sprachen wie Python gearbeitet hat, empfindet man Sprachen, die eine explizite Typangabe zur Compile-Zeit verlangen, komplizierter und langsamer in der Implementierung. Aber halt: in C++ hat sich seit C++11 einiges getan. Wie war es früher? Vor C++11 musste der Datentyp einer Variablen immer explizit angeben werden: int age&#8230;</p>
<p>The post <a href="https://creatronix.de/das-auto-keyword-modernes-c-plus-plus/">Das auto keyword &#8211; Modernes C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Wenn man lange mit dynamisch typisierten Sprachen wie Python gearbeitet hat, empfindet man<br />
Sprachen, die eine explizite Typangabe zur Compile-Zeit verlangen, komplizierter und langsamer in der Implementierung.</p>
<p>Aber halt: in C++ hat sich seit C++11 einiges getan.</p>
<h2>Wie war es früher?</h2>
<p>Vor C++11 musste der Datentyp einer Variablen immer explizit angeben werden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>int age = 42;
double weight = 86.6;
const char* name = "Joern";
</code></pre>
</div>
<h2>Das auto Keyword</h2>
<p>auto sagt dem Compiler: &#8220;Bestimme den Typ selbst, basierend auf der Initialisierung.&#8221;<br />
Das bedeutet aber auch, dass Variablen immer direkt initialisiert werden müssen!</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>auto age = 42;
auto weight = 86.6;
auto name = "Joern";
</code></pre>
</div>
<p>Den inferierten Typ können wir mit der Funktion typeid ausgeben lassen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>std::cout &lt;&lt; typeid(age).name() &lt;&lt; std::endl;
std::cout &lt;&lt; typeid(weight).name() &lt;&lt; std::endl;
std::cout &lt;&lt; typeid(name).name() &lt;&lt; std::endl;</code></pre>
</div>
<p>Dies gibt Folgendes aus:</p>
<pre><code>i
d
PKc
</code></pre>
<h2>Kurzer Ausflug &#8211; Name Mangling</h2>
<p>Name Mangling ist der Vorgang, bei dem der C++-Compiler Funktions- und Klassennamen intern kodiert, um zusätzliche Informationen wie Parameterlisten, Namespaces oder Templates in den Symbolnamen einzubetten. Dadurch können z. B. überladene Funktionen eindeutig unterschieden werden.</p>
<p>Während void foo(int) für den Menschen lesbar bleibt, wird sie im maschinennahen Code z. B. zu _Z3fooi. Dieses Verfahren ist notwendig für den Linker, führt aber zu Symbolnamen, die ohne Demangling schwer lesbar sind.</p>
<p>Außer unter MSVC gibt typeid(new_age).name() den vom Compiler gemangelten Type aus: Um trotzdem den menschenlesbaren Typ angezeigt zu bekommen, kann folgenden Hilfsfunktion benutzt werden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>template&lt;typename T&gt;
void output_type(const T&amp; var) 
{ 
    const char* mangled = typeid(var).name(); 
    int status;
    const std::unique_ptr&lt;char, void(*)(void*)&gt; demangled { 
        abi::__cxa_demangle(mangled, nullptr, nullptr, &amp;status), 
        std::free 
    }; 
    if (status == 0 &amp;&amp; demangled) 
        std::cout &lt;&lt; "Typ: " &lt;&lt; demangled.get() &lt;&lt; '\n'; 
    std::cout &lt;&lt; "Typ (mangled): " &lt;&lt; mangled &lt;&lt; '\n'; 
}</code></pre>
</div>
<h2>Schleifen mit auto</h2>
<p>Wenn wir beispielsweise über einen Vector iterieren wollen, musste das bis einschließlich C++03 so gemacht werden.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>std::vector&lt;int&gt; v = {1, 2, 3}; 
for (std::vector&lt;int&gt;::iterator it = v.begin(); it != v.end(); ++it) 
{
    std::cout &lt;&lt; *it &lt;&lt; '\n';
}</code></pre>
</div>
<p>Seit C++11 kann das auch viel kürzer geschrieben werden:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>for (const auto&amp; value : v){
    std::cout &lt;&lt; value &lt;&lt; '\n';
}</code></pre>
</div>
<p>Es empfiehlt sich hier, const auto&amp; zu verwenden, da sonst jedes Element aus dem Vektor kopiert würde.</p>
<h2>auto und const</h2>
<p>auto entfernt standardmäßig const- und Referenz-Qualifizierer.<br />
Wenn du sie erhalten willst, musst du sie explizit angeben – z. B. const auto&amp;.</p>
<h2>Fazit</h2>
<p>Das auto Keyword ist eine sehr nützliche Erweiterung in C++11, die den Code kürzer und lesbarer macht.<br />
Für Umsteiger von Sprachen wie Python ist es eine Erleichterung, da sie nicht mehr ständig an die Typen denken müssen.</p>
<p>The post <a href="https://creatronix.de/das-auto-keyword-modernes-c-plus-plus/">Das auto keyword &#8211; Modernes C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Compiler-Optionen für sauberes C++</title>
		<link>https://creatronix.de/compiler-optionen-fur-sauberes-c/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Mon, 07 Apr 2025 19:12:50 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Robotics]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=7310</guid>

					<description><![CDATA[<p>Motivation Nachdem ich mich in den letzten Wochen wieder vermehrt mit modernem C++ beschäftigt habe, möchte ich auch sicherstellen, dass mein Code maximal davon profitiert. Ein Aspekt davon ist es, möglichst sauberes C++ durch den Compiler zu erzwingen. Das geht am besten durch Compiler-Optionen. Was sind Compiler-Optionen? Compiler-Optionen oder auch Flags sind unverzichtbare Werkzeuge, um&#8230;</p>
<p>The post <a href="https://creatronix.de/compiler-optionen-fur-sauberes-c/">Compiler-Optionen für sauberes C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Nachdem ich mich in den letzten Wochen wieder vermehrt mit modernem C++ beschäftigt habe, möchte ich auch sicherstellen, dass mein Code maximal davon profitiert. Ein Aspekt davon ist es, möglichst sauberes C++ durch den Compiler zu erzwingen. Das geht am besten durch Compiler-Optionen.</p>
<h2>Was sind Compiler-Optionen?</h2>
<p>Compiler-Optionen oder auch Flags sind unverzichtbare Werkzeuge, um C++-Programme effizient, sicher und standard-konform zu erstellen. Sie ermöglichen die gezielte Steuerung des Kompilierungsprozesses – etwa durch die Auswahl des C++-Standards, die Aktivierung von Optimierungen oder die Kontrolle über Warnungen und Fehler.</p>
<p><strong>Besonders in größeren Projekten helfen Flags typische Programmierfehler frühzeitig zu erkennen und die Codequalität langfristig zu sichern.</strong></p>
<p>Ohne bewusst gesetzte Compiler-Optionen bleiben potenziell gefährliche Probleme oft unbemerkt, was sich negativ auf Wartbarkeit, Portabilität und Laufzeitverhalten auswirken kann.<br />
Nachdem wir in <a href="https://creatronix.de/wie-setze-ich-die-c-version-in-cmake/">Wie setze ich die C++ Version in CMake</a> schon mal via Compiler-Option die C++-Version gesetzt haben, kümmern wir uns heute um weitere Optionen.</p>
<h2>Wie füge ich Compiler-Optionen in CMake hinzu?</h2>
<p>Mit dem Kommando add_compile_options kannst Du die Flags setzen:</p>
<pre><code>add_compile_options(-W&lt;option_name&gt;)
</code></pre>
<h3>Beispiel</h3>
<pre><code>add_compile_options(-Wall)
</code></pre>
<h2>Die Optionen im Detail</h2>
<p>Die folgenden Option gelten für GCC und Clang.</p>
<h2>-Wall</h2>
<p>-Wall heißt nicht „alle Warnungen“, sondern: „Viele sinnvolle Standardwarnungen, die dich vor typischen Fehlern bewahren“<br />
-Wall erkennt zum Beispiel ungenutzte Variablen oder den beliebten Fehler Zuweisung statt Vergleichsoperator</p>
<h3>Beispiel unused variable</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>warning: unused variable 'x' [-Wunused-variable]
       38 |     int x = 42;
          |         ^
</code></pre>
</div>
<h3>Beispiel Zuweisungs- statt Vergleichsoperator</h3>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>if (x = 5) 
{
    std::cout &lt;&lt; x &lt;&lt; '\n';
}
</code></pre>
</div>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>warning: suggest parentheses around assignment used as truth value [-Wparentheses]
       39 |     if (x = 5) {
          |         ~~^~~
</code></pre>
</div>
<h2>-Wextra</h2>
<p>-Wextra kann zum Beispiel ungenutzte Parameter bei Funktionsaufrufen erkennen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>void unsused_param(std::string name)
{
    std::cout &lt;&lt; "unsused_param" &lt;&lt; '\n';
}
</code></pre>
</div>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>warning: unused parameter 'name' [-Wunused-parameter]
       35 | void unsused_param(std::string name)
          |                    ~~~~~~~~~~~~^~~~
</code></pre>
</div>
<h2>-Wpedantic</h2>
<p>Aktiviert Warnungen für alles, was gegen den offiziellen C++-Standard verstößt.<br />
Selbst wenn es der Compiler akzeptieren würde, wird eine Warnung ausgegeben.</p>
<p>Ein gutes Beispiel sind VLAs:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>int len = 3;
int vla[len];  
</code></pre>
</div>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>warning: ISO C++ forbids variable length array 'vla' [-Wvla]
       52 |     int vla[len];
          |         ^~~
</code></pre>
</div>
<h2>-Wconversion</h2>
<p>-Wconversion warnt bei impliziten Typumwandlungen, bei denen potenziell Informationen verloren gehen könnten – insbesondere bei „narrowing conversions“.</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>int z = 1.2;
std::cout &lt;&lt; z &lt;&lt; '\n';
</code></pre>
</div>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>warning: conversion from 'double' to 'int' changes value from '1.2e+0' to '1' [-Wfloat-conversion]
       49 |     int z = 1.2;
          |             ^~~
</code></pre>
</div>
<h2>-Werror</h2>
<p>Macht aus Warnungen Fehler und führt zum Build-Abbruch. Das ist nicht immer gewollt, deswegen kann man es beispielsweise nur für den Release-Build aktivieren:</p>
<pre><code>if(CMAKE_BUILD_TYPE STREQUAL "Release")
    add_compile_options(-Werror)
endif()
</code></pre>
<p>Beim Aufruf von CMake muss dann das folgende Flag an CMake übergeben werden:</p>
<pre><code>-DCMAKE_BUILD_TYPE=Release
</code></pre>
<h2>tl;dr;</h2>
<p>Am besten setzt ihr zum Ausprobieren -Wall, -Wextra und -Wpedantic.</p>
<h2>Bonus</h2>
<p>Unter Windows heißen die Option anders. Deswegen ist es sinnvoll eine Fallunterscheidung einzubauen:</p>
<div>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="CMake"><code>if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    message(STATUS "Compiler Clang")
    add_compile_options(-Wall -Wextra -Wpedantic)

elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    message(STATUS "Compiler GCC")
    add_compile_options(-Wall -Wextra -Wpedantic)

elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
    message(STATUS "Compiler MSVC")
    add_compile_options(/W4 /WX)
endif()</code></pre>
</div>
</div>
<p>The post <a href="https://creatronix.de/compiler-optionen-fur-sauberes-c/">Compiler-Optionen für sauberes C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to use the Eigen library in C++</title>
		<link>https://creatronix.de/how-to-use-the-eigen-library-in-cplusplus/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Fri, 29 Mar 2024 16:32:33 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=6934</guid>

					<description><![CDATA[<p>Motivation Working with matrices and vectors in C++ can be a bit cumbersome. The Eigen library is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms. It is used in many scientific and engineering applications. Eigen is versatile, efficient, and easy to use. It supports all matrix sizes, from small&#8230;</p>
<p>The post <a href="https://creatronix.de/how-to-use-the-eigen-library-in-cplusplus/">How to use the Eigen library in C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Working with matrices and vectors in C++ can be a bit cumbersome. The Eigen library is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms. It is used in many scientific and engineering applications. Eigen is versatile, efficient, and easy to use. It supports all matrix sizes, from small fixed-size matrices to arbitrarily large dense matrices, and even sparse matrices.</p>
<h2>Installation</h2>
<p>Eigen is a header-only library. You can download it from the <a href="https://eigen.tuxfamily.org/index.php?title=Main_Page">official website</a> and include it in your project.<br />
Under Windows, you can use nuget to install Eigen. Just search for Eigen3 in the nuget package manager and install it.<br />
Under Linux, you can install Eigen with the package manager:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>sudo apt-get install libeigen3-dev
</code></pre>
</div>
<h2>Mac OS</h2>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-bash" data-lang="Bash"><code>brew install eigen</code></pre>
</div>
<h2>Setup</h2>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="CMake"><code>set(CMAKE_CXX_STANDARD 14)
include_directories(/opt/homebrew/opt/eigen/include/eigen3)</code></pre>
</div>
<h2>Usage</h2>
<p>Here is a simple example of how to use Eigen in your C++ code:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>#include &lt;iostream&gt;<iostream>
#include &lt;Eigen/Dense&gt;

int main()
{
    Eigen::MatrixXd m(2, 2);
    m(0, 0) = 3;
    m(1, 0) = 2.5;
    m(0, 1) = -1;
    m(1, 1) = 4.0;
    std::cout &lt;&lt; m &lt;&lt; std::endl;
}
</iostream></code></pre>
</div>
<p>The matrix <code>m</code> is a 2&#215;2 matrix.<br />
The d in the <code>MatrixXd</code> stands for double. You can also use <code>MatrixXf</code> for float or <code>MatrixXi</code> for int.<br />
Dynamic sizes are indicated by the <code>X</code> in the type name.<br />
Fixed-size matrices are defined with the number of rows and columns like <code>Matrix2d</code> for a 2&#215;2 matrix.</p>
<p>You can access the elements of the matrix with the <code>()</code> operator.</p>
<h2>Operands</h2>
<p>An interesting feature of Eigen is the operator overloading.<br />
You can use the standard arithmetic operators like <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code> with Eigen matrices and vectors.</p>
<h2>Initialization</h2>
<p>To initialize a matrix you can also use the <code>&lt;&lt;</code> operator, which provides a more concise way to initialize a matrix:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>Eigen::MatrixXd m2(2, 2);
m2 &lt;&lt; 1, 2,
      3, 4;
</code></pre>
</div>
<h2>Transpose</h2>
<p>You can transpose a matrix with the <code>transpose()</code> method:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>Eigen::MatrixXd m3(2, 3);
m3 &lt;&lt; 1, 2, 3, 
     4, 5, 6;
std::cout &lt;&lt; "Here is the matrix m:" &lt;&lt; std::endl &lt;&lt; m3 &lt;&lt; std::endl;
std::cout &lt;&lt; "Here is the matrix m^T:" &lt;&lt; std::endl &lt;&lt; m3.transpose() &lt;&lt; std::endl;</code></pre>
</div>
<h2>Determinant</h2>
<p>You can calculate the determinant of a matrix with the <code>determinant()</code> method:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>Eigen::MatrixXd m5(2, 2);
m5 &lt;&lt; 1, 2,
      3, 4;
std::cout &lt;&lt; "Here is the matrix m:" &lt;&lt; std::endl &lt;&lt; m5 &lt;&lt; std::endl;
std::cout &lt;&lt; "Here is the determinant of m:" &lt;&lt; std::endl &lt;&lt; m5.determinant() &lt;&lt; std::endl;
</code></pre>
</div>
<h2>Inverse</h2>
<p>You can calculate the inverse of a matrix with the <code>inverse()</code> method:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>Eigen::MatrixXd m4(2, 2);
m4 &lt;&lt; 1, 2,
      3, 4;
std::cout &lt;&lt; "Here is the matrix m:" &lt;&lt; std::endl &lt;&lt; m4 &lt;&lt; std::endl;
std::cout &lt;&lt; "Here is the inverse of m:" &lt;&lt; std::endl &lt;&lt; m4.inverse() &lt;&lt; std::endl;
</code></pre>
</div>
<h2>Links</h2>
<p><a href="https://libeigen.gitlab.io/">https://libeigen.gitlab.io/</a></p>
<p>The post <a href="https://creatronix.de/how-to-use-the-eigen-library-in-cplusplus/">How to use the Eigen library in C++</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Modern C++: How to use tuples</title>
		<link>https://creatronix.de/modern-cplusplus-how-to-use-tuples/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Sun, 24 Mar 2024 08:08:39 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Software Engineering & Programming]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=6926</guid>

					<description><![CDATA[<p>Motivation Python supports the concept of multiple return values since its first version. C++ introduced the concept in C++11. Let&#8217;s have a look how it works: How to use it You need to include the header include &#60;tuple&#62; You have to declare return parameter of your function e.g. std::tuple&#60;int, int&#62; You use the function make_tuple:&#8230;</p>
<p>The post <a href="https://creatronix.de/modern-cplusplus-how-to-use-tuples/">Modern C++: How to use tuples</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Python supports the concept of multiple return values since its first version.<br />
C++ introduced the concept in C++11. Let&#8217;s have a look how it works:</p>
<h2>How to use it</h2>
<ol>
<li>You need to include the header <code>include &lt;tuple&gt;</code></li>
<li>You have to declare return parameter of your function e.g. <code>std::tuple&lt;int, int&gt;</code></li>
<li>You use the function make_tuple: <code>return std::make_tuple(x, y);</code></li>
<li>On the caller side you need to tie the return values to local variables e.g. <code>std::tie(x_pos, y_pos)</code></li>
</ol>
<p>That&#8217;s all!</p>
<h2>Example Code</h2>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="C++"><code>#include <iostream>
#include <tuple>
#include <vector>

std::tuple&lt;double, double&gt; calculate_mean_and_variance(std::vector<double> measurements)
{
    double sum = 0.0;
    for (double num : measurements) {
        sum += num;
    }
    double _mean = sum / measurements.size();

    double sq_sum = 0.0;
    for (double num : measurements) {
        sq_sum += (num - _mean) * (num - _mean);
    }

    double variance = sq_sum / measurements.size();

    return std::make_tuple(_mean, variance);
}

int main()
{
    std::vector<double> measurements = { 1, 2, 3, 4 };
    double mean, variance;
    std::tie(mean, variance) = calculate_mean_and_variance(measurements);
    std::cout &lt;&lt; mean &lt;&lt; ", " &lt;&lt; variance &lt;&lt; std::endl;
    return 0;
}
</double></double></vector></tuple></iostream></code></pre>
</div>
<p>The post <a href="https://creatronix.de/modern-cplusplus-how-to-use-tuples/">Modern C++: How to use tuples</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Wie setze ich die C++ Compiler-Version in CMake</title>
		<link>https://creatronix.de/wie-setze-ich-die-c-version-in-cmake/</link>
		
		<dc:creator><![CDATA[Jörn]]></dc:creator>
		<pubDate>Mon, 04 Mar 2024 07:04:45 +0000</pubDate>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Software Engineering & Programming]]></category>
		<guid isPermaLink="false">https://creatronix.de/?p=6910</guid>

					<description><![CDATA[<p>Motivation Im Rahmen meines Udacity Nanodegree Robotics Software Engineer musste ich mit C++17 arbeiten, da ROS Noetic Ninjemys Sprachfeature von C++17 verwendet. Nun wollte ich wissen, wie ich die C++-Version in CMake setze. Top Level Cmake-Datei In der Top-Level CMake-Datei setze ich die C++-Version folgendermaßen: set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) Bei einigen Compilern wie dem clang&#8230;</p>
<p>The post <a href="https://creatronix.de/wie-setze-ich-die-c-version-in-cmake/">Wie setze ich die C++ Compiler-Version in CMake</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Motivation</h2>
<p>Im Rahmen meines Udacity Nanodegree Robotics Software Engineer musste ich mit C++17 arbeiten, da ROS Noetic Ninjemys Sprachfeature<br />
von C++17 verwendet. Nun wollte ich wissen, wie ich die C++-Version in CMake setze.</p>
<h2>Top Level Cmake-Datei</h2>
<p>In der Top-Level CMake-Datei setze ich die C++-Version folgendermaßen:</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="CMake"><code>set(CMAKE_CXX_STANDARD 17) 
set(CMAKE_CXX_STANDARD_REQUIRED ON)</code></pre>
</div>
<p>Bei einigen Compilern wie dem clang unter macos bekommt ihr nicht automatisch alle neuen Sprachfeatures, ihr braucht dann noch das compiler flag -stdlib=libc++</p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-cpp" data-lang="CMake"><code>set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    message(STATUS "Using Clang - setting -stdlib=libc++")
    add_compile_options(-stdlib=libc++)
    add_link_options(-stdlib=libc++)
endif()
</code></pre>
</div>
<p>The post <a href="https://creatronix.de/wie-setze-ich-die-c-version-in-cmake/">Wie setze ich die C++ Compiler-Version in CMake</a> appeared first on <a href="https://creatronix.de">Creatronix</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
