Sunday, November 4, 2018

A brief intro to C++11 features

17. delete function
if you do
void func(int)
void func(double) = delete

then when you do func(1.1) it will not be typecasted to int and call func(int), but will throw an error.

16. default function
A way to provide default implementation of the function, like a constructor.

15. foreach
for (auto iter: myContainer)    //myContainer is any type that has begin() and end(). Read only.
for (auto &iter:myContainer) //Read/Write access


14.delegating constructor
Replacement for the typical 'init()' function.
Disadvantage is - it can only be invoked at the beginning of constructor call, not laters.

myClass() //delegating constr
myClass(type a) : myClass() { do_something_on_a();}

Also, data members of the class can be initialized in the class declaration itself. All the objects will have this initial value, which may later be changed.

13.constexpr
Compile time evaluation of a const expression, which will eventually save cycles during the run time.


12.enums : Strong typed enum class
enum class car{german, japanese, korean}
enum class bike{german, american, Indian}

a = car::german; b = bike::german
In C++03, a==b will return true, but in C++11, it will not; but it will give a compile error because == is not overloaded for car and bike.

11. nullptr
In C++03, NULL is 0; so we have a new definition, especially for removing this ambiguity.

9. final (earlier solution was to have private constructor)
class - no class can be derived from the final class.
virtual function - no class can override the function.

8.  override
To fix the name hiding problem.

Base class
virtual void f (int);
Derived class
virtual void f(float);

If we add override keyword to the derived::f, compile will throw an error to highlight the fact that overriding will not be possible. Either remove override keyword (not the desired outcome) or correct the signature.

7. lambda expressions
A very powerful feature of functional programming - anonymous function
std::cout << [](std::string a, std::string b){return (a+b);} ("abc", "def");
Having this line in main will print 'abcdef';

It can access local variables too.

6. auto
Typically useful while iterating.
A drawback is 'readability is lost'; but in a good IDE it can be overcome.

Automatically infers the type from the rvalue (but it also means, it needs a rvalue, otherwise how can it infer?)

5. Static assertion
Compile time assert (in addition to the C++03 run time assert)
C++03 : assert (ptr != NULL);
C++11 : static_assert(sizeof(char) == 1);


4. Initialiser list
Similar to array initialisation is vector(any other container) initialisation now.

You can also define your own initialiser list constructor for the class like this -
#include
class MyClass
{
    vector vec;
    public:
    MyClass(const std::initializer_list &v)
    {
        for (initializer_list::iterator iter = v.begin(); iter!=v.end(); ++iter)
            vec.push_back(*iter);
    }
};

MyClass obj = {1,3,5,9};
MyClass obj{1,3,5,9};


3. Variadic templates
... is called parameter pack.

template
void log(T first, Args... args);

the function log can take any number/type of arguments equal to or more than 1.

A good example given here - https://thispointer.com/c11-variadic-template-function-tutorial-examples/

2. rvalue references
lvalue = any object that occupies some identifiable location in memory
rvalue = anything that is not a lvalue

Simple examples -
int x = 0;                                        //x is lvalue, 0 is rvalue
int &x1 = x;                                   //x1 is lvalue
int *p = &x;                                   //p is lvalue
int y = x+2;                                    //(x+2) is rvalue, y is lvalue
int *p1 = & (x+2);                         //error - (x+2) doesnt have a memory, its a rvalue
int result = add (3,4);                     //add(3,4) is rvalue, result is lvalue
int add(int a, int b)
{
    return (a+b);                              //(a+b) is rvalue
}

Usage:
void abraCaDabra(int &a){}
void abraCaDabra(int && a) {}

You can call using abraCaDabra(i) (will call lvalue) or abraCaDabra(5) (will call rvalue)
With c++03, it will give compile error.


1. Move Semantics
Unlike Copy constructor, move constructor moves the object to the new one, thereby the old object becomes unusable (mostly).

Move constructor : Inexpensive shallow copy
MyClass (Myclass && rhs)
{
    member = rhs.member;
    ptr = rhs.ptr // In a copy constructor, ptr would be newly allocated, and then contents copied.
}

No comments:

Post a Comment