Features of
modern C++

Johan Burell
What makes C++ hard?
Challenges
- Complexity
- Memory management
- Legacy (primarily from C)
- Multi paradigm
- (Compilation)
Strengths
- Flexibility
- Performance
- Widespread usage
- Multiparadigm
- Type safe (if done right...)
A "new" language
Within C++,there is a much smaller and cleaner language struggling to get out.- Bjarne Stroustrup

...and no, that smaller and cleaner language is not Java or C#.- Bjarne Stroustrup

You can write C++ programs that are statically type safe and have no resource leaks. You can do that without loss of performance and without limiting C++’s expressive power. This supports the general thesis that garbage collection is neither necessary nor sufficient for quality software. Our core C++ guidelines makes such code simpler to write than older styles of C++ and the safety can be validated by tools that should soon be available as open source.
- Bjarne Stroustrup
The state of C++ today

Timeline
C++11
(aka C++0x)
auto, lambdas, thread model, initializer lists, typed enums, smart pointers... etc
C++14
(aka C++1y)
auto return type, variable templates, generic lambdas and capture expressions... etc
C++17
(aka C++1z)
File system, Parallellism, various library fixes... "TBD"
New language features!
Const expression / foreach-loops
Subtitle
#include <iostream>
using namespace std;
constexpr int numElements() { return 3; }
int myArr[numElements() + 2];
int main() {
for(int &a: myArr) {
a = 2;
}
cout << myArr[3] << endl;
return 0;
}
Move semantics / initializer-lists
Subtitle
struct MyStruct {
int a;
float b;
};
MyStruct modify(MyStruct myStruct) {
myStruct.a = 5;
return myStruct;
}
int main () {
MyStruct myStruct{2, 1.2};
myStruct = modify(myStruct);
return 0;
}Smart pointers
Subtitle
#include <memory>
using namespace std;
struct MyObject {
int value;
};
void aTypicalFunc(unique_ptr<MyObject>& smartObj, MyObject* dumbObj) {
smartObj->value = 5; dumbObj->value = 3;
}
int main() {
unique_ptr<MyObject> myObj = make_unique<MyObject>();
MyObject* myLeakingObject = new MyObject();
//unique_ptr<MyObject> myObj2 = myObj; // Compile err
unique_ptr<MyObject> myObj3 = move(myObj); // Valid
aTypicalFunc(myObj3, myLeakingObject);
shared_ptr<int> p1(new int(5));
shared_ptr<int> p2 = p1; //Both now own the memory.
p1.reset(); //Memory still exists, due to p2.
p2.reset(); //Deletes the memory, no owners left
return 0;
}
Auto / decltype
Subtitle
struct SomeStruct {
SomeStruct(auto x, auto y) : someVal{x}, someOtherVal{y} {}
int someVal;
private:
double someOtherVal;
};
void changeObj (auto& myObj) {
myObj.someVal = 7;
}
int main() {
SomeStruct myStruct{3, 3.14};
changeObj(myStruct);
decltype(myStruct) someOtherStruct{5, 1.2};
return 0;
}Lambdas and more decltype
Subtitle
template<class Lhs, class Rhs>
auto addFunc(const Lhs &lhs, const Rhs &rhs)
-> decltype(lhs+rhs)
{ return lhs + rhs; }
auto mulFunc = [](auto a, auto b){ return a * b; };
int main() {
auto myVal = 2;
auto myVal2 = 3;
auto result = addFunc(myVal, myVal2) - mulFunc(myVal, myVal2);
auto closure = [&](){ myVal = myVal2; };
closure();
return 0;
}Threads / Futures / Promises
Subtitle
#include <iostream> // std::cout
#include <functional> // std::ref
#include <thread> // std::thread
#include <future> // std::promise, std::future
using namespace std;
void print_int(future<int>& fut) {
int x = fut.get();
cout << "value: " << x << '\n';
}
int main ()
{
promise<int> prom; // create promise
future<int> fut = prom.get_future(); // engagement with future
thread th1(print_int, ref(fut)); // send future to new thread
prom.set_value(10); // fulfill promise
// (synchronizes with getting the future)
th1.join();
return 0;
}Override
Subtitle
struct Base {
virtual float some_func(float) = 0;
virtual float some_other_func() final { return 3.9; };
};
struct Derived : Base {
float some_func(float a) override {
return a * 2;
}
};
int main() {
auto d = Derived();
auto e = d.some_func(d.some_other_func());
return 0;
}GSL
(Guidelines Support Library)

Span (slices)
Subtitle
#include "gsl.h"
using namespace gsl;
int doStuff(span<int> stuff) {
int sum = 0;
for(int& a: stuff) {
sum += a;
}
return sum;
}
int main() {
int stuff[] = {1,2,3,4,5};
int sum = doStuff(as_span(stuff).subspan(1, 3));
return 0;
}Owner
Subtitle
#include "gsl.h"
#include<iostream>
using namespace std;
using namespace gsl;
void doStuff(owner<int*> data, not_null<string*> str) {
cout << *str << endl;
}
int main() {
int* data = new int[5];
//string* str = nullptr; // Error
string* str = new string("Hej");
doStuff(data, str);
return 0;
}Further reading
(Cling)
Questions?
Thanks for listening!
Features of modern C++
By burre83
Features of modern C++
- 716