C++

Unsere Hauptprogrammiersprache ist eindeutig C++. Unser Statement dazu:

Wir lieben C++!!!

Was, seid ihr verrückt? Das kann doch nicht euer Ernst sein! C++ ist doch: C++ ist gaga... Nein, es ist unser Ernst: wir lieben es, weil C++ einfach super ist!!! 

Na ja, so einfach ist es vielleicht nicht...

Es ist eine tolle Mischung von low-level, performance-kritischen, OO, generischen und funktionalen Features! Und es eine der wenigen  Sprachen, wo man beides haben kann: hohes Abstraktionsniveau und eine "Bare Metal" Performace! Von den Sprachen, die ich bisher kenne, hat mich nur die ML-Familie vielleicht noch mehr beeidruckt, also: OCaml, F# (und, ja... auch Haskell).1

Jaaa, ich weiss, C++ ist nicht ganz ohne Tadel: es ist komplex! Na und? Seien wir ehrlich, welche Programmiersprache ist es nicht?

Wichtiger ist vielleicht, dass es nicht perfekt ist: früher (C++98) dachte ich z.B. dass man mit Templates und Überladen der Operatoren alles machen könnte. Dann hat es sich aber herausgestellt, dass für manche Sachen man einfach doch neue Sprachkonstrukte braucht

Aber jetzt sind die da: in den neuen C++11 und C++14 Standards. Es hat sich eine Menge geändert! Als Nächstes möchte ich einge vielleicht unbekannte Fakten über "modernes" C++ vorstellen:

Wie man mit C++ programmieren kann.

Man kann natürlich in dem guten, altbewährten OO-Stil arbeiten. Man kann aber auch (Stand von 2014):

wie hier

 // the Maybe monad:
template<typename T>
struct maybe {
// ....
};

// a non-monadic function;
int foo(int x,int y) {
return x*y;
}

// lift it into the monad:
auto mfoo = mlift<maybe>(&foo);

// and work inside the monad!!
auto res = mfoo(maybe<int>(2), maybe<int>(3));
assert(res == maybe<int>(6));
oder wie hier (FTL), die C++ Standardbibliothek um funktionale Features erweitern:
  // curry a function
auto plus = ftl::curry(std::plus<int>);
auto addOne = plus(1);

// use an applicative
int algorithm(int, int, int);
ftl::maybe<int> maybeGetAValue();
ftl::maybe<int> maybeGetAnother();
ftl::maybe<int> maybeGetAThird()

using ftl::operator%;
using ftl::operator*;
auto result =
ftl::curry(algorithm) % maybeGetAValue() * maybeGetAnother() * maybeGetAThird();

// stack monads with transformers!
template<typename T> using listM = ftl::maybeT<std::list<T>>;
Eine weitere Bibliothek findet man z.B. hier, mit einer interessanten Begründung für den Sinn und Zweck der funktionaler Programmierung in C++:

While switching to a functional languages for a project has its benefits, use of functional languages often doesn't take advantage of preexisting developer expertise and the resulting code sometimes has difficult to solve performance issues[15,7].

Our goal is to implement modern functional programming in C++ directly. By doing so, we hope to present a framework that has familiar usage to C++ programmers, but is also powerful enough to implement modern functional programming designs.

wie zum Beispiel zum Testen:
 using namespace igloo; // the test framework!

Describe(A_Cell)
{
It(should_have_coordinates)
{
Cell cell(3,4);
Assert::That(cell.getX(), Equals(3));
Assert::That(cell.getY(), Equals(4));
}

It(can_detect_if_its_a_neighbour)
{
Cell cell(1,5);
Cell neighb(2,4);
Assert::That(cell.isNeighbourTo(neighb), IsTrue());
}
};
oder um MATLAB zu ersetzen wie hier. Ein Zitat vom Autor der Bibliothek:

We still think EDSL in C++ is a valid use case as it bridges the gap between the (potential) efficiency of C++ compiled code and a high level of abstraction.

#include "Die.h"
#include <iostream>

template<typename DIE>
class GameFourWinsT
{
DIE die;
public:
void play(std::ostream& out = std::cout) {
if (die.roll() == 4) {
out << "You won!\n";
}
else {
out << "You lost!\n";
}
}
};

typedef GameFourWinsT<Die> GameFourWins;
GameFourWinsT game;
game.play();
und damit z.B. Mixins in C++ realisieren.
constexpr int multiply (int x, int y)
{
return x * y;
}

// evaluate this at compile time
const int val = multiply( 10, 10 );
(Es geht auch mit Templates, aber viel schwieriger!)
und zwar mit Hilfe von benutzerdefinierten Literalen:
assert(1_kg == 2.2_lb); // Kilos und Pfunde
oder
time t =1.0_s;
speed s1 = 100.0_m / 9.8_s; // very fast for a human
speed s2 = 1.2_km / 0.5_h; // slow going
speed s3 = 1.2_km / 30.0_min; // the same speed

// speed s2 = 100 / 9.8s; // compile error
und zwar mit der libcppa Bibliothek, Erlang-echt mit Pattern Matching und Actors:
// A Generic Asynchronous IPv4 Server: 
template <typename Connection>
void server(uint16_t port, char const* addr, actor_ptr handler)
{
auto acceptor = network::ipv4_acceptor::create(port, addr);

receive_loop
(
// libcppa's blocking API
on(atom("accept")) >> [&]
{
if (util::poll(acceptor->file_handle()) &&
(auto io = acceptor->try_accept_connection()))
{
auto conn = spawn<Connection>((*io).first, (*io).second);
send(handler, atom("connection"), conn);
}
self << last_dequeued();
},
on(atom("kill")) >> [] { self->quit(); }
);
}
z.B. mit einer Mischung aus Laufzeit- und Template- Metaprogrammierung mit der Boost Fusion Bibliothek:
BOOST_FUSION_DEFINE_STRUCT(
(example), header,
(example::magic_t, magic)
(example::version_t, version)
(uint32_t, length)
(std::unordered_map, hdr_props)
(example::msg_type_t, msg_type)
(std::vector, vals)
)
Ähnliches ginge wohhl auch mit Boost Hana!

Übrigens, wussten Sie schon von Online C++ Compilern? Und von den Dependency-Injection Lösungen, oder von dem "Modernizer", und dem Address- oder Thread-"Sanitizern", oder vielleicht vom ACF Komponenten Framework, und, und, und...

                    (C++ logo by @biicode)

Was man mit C++ programmieren kann.

Sie wissen es bestimmt dass man C++ folgendes sehr gut erstellen kann:
obwohl mann nicht:
Aber wussten sie auch dass folgende Sachen (Stand von 2014) auch gehen?

Man kann seine Anwendung in C++ erstellen und mit Emscripten in Javascript übersetzen, dann läuft es in jedem Browser! Lesen Sie hier über "Emscripten & asm.js: C++'s role in the modern web". Ein Zitat vom Autor:

Overall, performance is around 50-67% of native speed, and still improving.

Already fast enough for many applications, even performance sensitive ones like game...

D.h. sogar Gaming-Engines kann man damit in den Browser portieren!

Um eine GUI für ihr gerande mit Emscripten portiertes Programm zu ertellen könnten sie auf Javascript zurückgreien, oder aber es in C++ zu schreiben - es gibt einen Qt-Port auf Emscripten! 

Gut, könte ein Overkill sein... Oder, man nimmt den Duetto-Compiler (jetzt wohl zu Cheerp umbennant), schreibt sowohl Client und Server Code in C++, un lässt es mit für den Browser und den Server übersetzen. Man kann es dann sogar direkt im Browser debuggen2! Zitat:

The com­piler will split the code auto­mat­i­cally in the client part (com­piled to JavaScript) and server part (com­piled to native code)

Everything else (including client to server remote procedure calls, serialization and deserialization, etc.) will work automagically!

Dafür gibt es eine Reihe von Frameworks (wie CppCMS, Wt, Treefrog usw.). Ich habe früher ein wenig darüber geschrieben, aber neuerdings gibt es eine deutschsprachige Seite, die sich ausschliesslich mit diesem Thema befasst. Lesen Sie wie man das bei Dropbox macht, warum C++ dafür wie geschaffen ist, und warum man manchmal so ein Framework selber schreiben soll. Die häufigste Wahl ist allerdings Marmalade - viele Games wurden damnit gemacht. Und zwar komplizierte wie: "Lara Croft and the Guardian of Light" und "Call of Duty: World at War Zombies", aber auch kleinere wie "Doodle Jump".
mit Microsoft's Casablanca REST-Framework! Damit kann man entweder die Cloud-Services konsumieren (wie hier), oder abfragen und in einen neuen Service kombinieren (eben ein Mash-Up erstellen - schauen Sie sich z.B. den Code hier)!
Aber, das wussten Sie wahrscheinlich schon. Trotzdem kann man sich hier zwichem dem schon erwähntem Actor-Stil (mit der libcppa Bibliothek) oder dem P2P Stil entscheiden, wie z.B. hier, mit der RTI Connext Bibliothek. Ein Zitat vom Autor der letzteren scheint hier angebracht zu sein als eine Art Zusammenfassung:

If I had to give you one reason why C++ is king (and this isn’t changing anytime soon) it would be this: C++ lets you create very powerful abstractions with zero or minimal runtime impact. Few languages can offer both.


--
  1. Na gut, Lisp ist auch nicht schlecht, aber wenn man im OCaml gesehen hat, dass es auch ohne Klammern geht, dann denkt man sich: sind die Macros wirklich so toll? Aber wir schweifen ab.
  2. Zitat: "Cheerp fully supports the SourceMaps standard, which makes it possible to debug your original C++ code directly in the browser. Set break points, step the execution and see the original C++ code when an exception happens."
  3. Erlang ist die Vorzeigesprache für fehlertolerante, verteile Systeme, sein Motto: "Build massively scalable soft real-time systems" .
Nach oben