## Cpp11 * A quick reminder of lesser known features * static_assert * Uniform initialization * In-class initialization of non-static variables * initializer_list * alias * Template alias * C'tor inheritance * Attributes * Data structure alignment ___ ## static_assert ```cpp template void swap(T& a, T& b) { static_assert(std::is_copy_constructible::value, "Swap requires copying"); static_assert(std::is_nothrow_move_constructible_v && std::is_nothrow_move_assignable_v); auto c = b; b = a; a = c; } ``` **Rationale**: Preventing compilation on user defined conditions (usually specific types). Performs compile-time assertion checking. Usually used with `` library. The message is optional from C++17. ___ ## C++98/03 initialization

int a;                            // undefined value                           
int b(5);                         // direct initialization, b = 5              
int c = 10;                       // copy initialization, c = 10               
int d = int();                    // default initialization, d = 0             
int e();                          // function declaration - "most vexing parse"

int values[] = { 1, 2, 3, 4 };    // brace initialization of aggregate         
int array[] = { 1, 2, 3.5 };      // C++98 - ok, implicit type narrowing       

struct P { int a, b; };                                                        
P p = { 20, 40 };                 // brace initialization of POD               

std::complex<double> c(4.0, 2.0); // initialization of classes                 

std::vector<std::string> names;   // no initialization for list of values      
names.push_back("John");                                                       
names.push_back("Jane");                                                       
___ ## C++11 initialization with {}

int a;                               // still undefined value                    
int b{5};                            // brace initialization, b = 5              
int c{};                             // brace initialization, c = 0              

int values[] = { 1, 2, 3, 4 };       // brace initialization of aggregate        
int array[] = { 1, 2, 3.5 };         // C++11: error - implicit type narrowing   

struct P { int a, b;                                                             
P p = { 20, 40 };                    // brace initialization of POD              

std::complex<double> c{4.0, 2.0};    // brace initialization calls adequate c-tor

std::vector<std::string> names = { "John", "Jane" };                             
                                    // brace initialization of vector           
**Rationale**: eliminate problematic initialization cases from C++98, initialization of STL containers, have one universal way of initialization. ___ ## In-class initialization of non-static variables ```cpp struct Foo { Foo() {} Foo(std::string a) : a_(a) {} void print() { std::cout << a_ << std::endl; } private: std::string a_ = "Foo"; // C++98: error, C++11: OK static const unsigned VALUE = 20u; // C++98: OK, C++11: OK }; Foo().print(); // Foo Foo("Bar").print(); // Bar ``` ___ ## `std::initializer_list` ```cpp auto values = {1, 2, 3, 4, 5}; // values is std::initializer_list std::vector v = {1, 2, -3}; // creates a vector from // std::initializer_list ``` * Defined in initializer_list header * Elements are kept in an array * Elements are immutable * Elements must be copyable * Have limited interface and access via iterators - begin(), end(), size() * Should be passed to functions by value ___ ## Constructor priority

template<class Type>                                               
class Bar {                                                        
    std::vector<Type> values_;                                     
public:                                                            
    Bar(std::initializer_list<Type> values) : values_(values) {}   
    Bar(Type a, Type b) : values_{a, b} {}                         
};                                                                 

Bar<int> c = {1, 2, 5, 51};   // calls std::initializer_list c-tor
Bar<int> d{1, 2, 5, 51};      // calls std::initializer_list c-tor
Bar<int> e = {1, 2};          // calls std::initializer_list c-tor
Bar<int> f{1, 2};             // calls std::initializer_list c-tor
Bar<int> g(1, 2);             // calls Bar(Type a, Type b) c-tor  
Bar<int> h = {};              // calls std::initializer_list c-tor
                       // or default c-tor if exists
Bar<std::unique_ptr> c = {new int{1}, new int{2}};                
// error - std::unique_ptr is non-copyable                        
C-tor with std::initializer_list has greater priority, even if other c-tors match. ___ ## Exercise 1 * Open project streamer * Add two C'tor: * first will take initializer_list * second const StreamInfo& * initialize vector in initialization list ___ ## Type aliasing ```cpp typedef std::ios_base::fmtflags Flags; using Flags = std::ios_base::fmtflags; // the same as above Flags fl = std::ios_base::dec; ``` ```cpp typedef std::vector> SocketContainer; std::vector> typedef SocketContainer; // correct ;) using SocketContainer = std::vector>; ``` **Rationale**: More intuitive alias creation. A type alias is a name that refers to a previously defined type. It could be created with typedef. From C++11 type aliases should be created with `using` keyword. ___ ### Template aliases ```cpp struct ThemedLabelToogleButton { ... } template using ButtonMap = std::map; ButtonMap> my_map; // std::map ``` Type alias can be parametrized with templates. It was impossible with typedef. Template aliases cannot be specialized. ___ ### Constructors inheritance ```cpp struct A { explicit A(int); int a; }; struct B : A { using A::A; // implicit declaration of B::B(int) B(int, int); // overloaded inherited Base ctor }; ``` * Derived class constructors are generated implicitly, only if they are used * Derived class constructors take the same arguments as base class constructors * Derived class constructor calls according base class constructor * Constructor inheritance in a class that adds a new field might be risky - new fields can be uninitialized ___ ## Exercise 2 * Open project streamer * Add aliases for ip adress, port and vlan. ___ ## Attributes ___ ### Standard attributes * [[noreturn]] - function does never return, like std::terminate. If it does, we have UB * [[deprecated]] (C++14) - function is deprecated * [[deprecated("reason")]] (C++14) - as above, but compiler will emit the reason * [[fallthrough]] (C++17) - in switch statement, indicated that fall through is intentional * [[nodiscard]] (C++17) - you cannot ignore value returned from function * [[maybe_unused]] (C++17) - suppress compiler warning on unused class, typedef, variable, function, etc. ___ ## `[[noreturn]]` attribute ```c++ [[noreturn]] void f() { throw "error"; // OK } [[noreturn]] void q(int i) { if (i > 0) { throw "positive"; } // the behavior is undefined if called with argument <=0 } ``` ___ ## `[[deprecated]] attribute` Attributes for namespaces and enumerators are available from C++17. ```c++ [[deprecated("Please use f2 instead")]] int f1(); enum E { foo = 0, bar [[deprecated]] = foo }; E e = bar; // Emits warning namespace [[deprecated]] old_stuff { void legacy(); } old_stuff::legacy(); //Emits warning ``` ___ ## `[[fallthrough]]` attribute ```c++ void f(int n){ void g(), h(), i(); switch(n) { case 1: case 2: g(); [[fallthrough]]; case 3: // no warning on fallthrough h(); case 4: // compiler may warn on fallthrough i(); [[fallthrough]]; // illformed, not before a case label } } ``` ___ ## `[[nodiscard]]` attribute ```c++ struct [[nodiscard]] error_info {}; error_info process(Data*); // ... void passMessage() { auto data = getData(); process(data); // compiler warning, discarding error_info } ``` ___ ## `[[maybe_unused]]` attributes ```c++ [[maybe_unused]] void f([[maybe_unused]] bool thing1, [[maybe_unused]] bool thing2) { [[maybe_unused]] bool b = thing1 && thing2; assert (b); // in release mode, assert is compiled out, and b is unused // no warning because it is declared [[maybe_unused]] } // parameters thing1 and thing2 are not used, no warning ```