Frequently used C++11 Features

auto 


In C++98, you must specify the type of an object when you declare it. C++11 takes advantage of this, letting you declare objects without specifying their types. auto is now a  sort of placeholder for a type, telling the compiler it has to deduce the actual type of a variable that is being declare.

auto i = 30; // i is an int
auto l = 90LL // l is an lon long
auto c = ‘a’ ; // char

vector<int> vi;

vector<int>::iterator ci = vi.begin();

instead we ca declare the iterator like this.

auto ci = vi.begin();


nullptr – At last, C++ has a keyword that designates a null pointer constant. nullptr replaces the bug prone NULL macro and the literal 0 that have been used as null pointer substitutes for many years.

Void f(int);  // Line 1
Void f(char *); // Line 2

// C++ 98
f(0) ; // Which f is called ? Ambiguous

// C++11
f(nullptr) ; // UnAmbiguous. Calls Line 2


Range based for loops



C++11 extends the syntax of the for statement to allow for easy iteration over a range of elements. This form will iterate over each element in the list. It works for C-style arrays, initializer lists, and any type that has begin() and end() functions defined for it that return iterators.

For example –

Std::map<std::string, std::vector<int>> map;
Std::vector<int> v;

v.push_back(1);
v.push_back(2);
v.push_back(3);

map[“ONE”] = v;

for(auto& mapIter : map)
{
            Cout<<mapIter.first;
            for(auto vecIter : mapIter.second)
            {
                        Cout<<vectorIter;
            }
}


Override and final


Virtual methods was badly designed in C++98, because there was’nt a mandatory mechanism to mark virtual methods as overridden in derived classes. It is possible to accidentally create a new virtual function, when one intended to override a base class function. For example :

Class Base
{
            Public:
            Virtual void func() const
            {
                        Cout<<”This is constant BASE :”;
            }
};

Class derived : public base
{
            Public:
            Virtual void func()
            {
                        Cout<<”This is a Non Constant DERIVED : ”;
            }
};


Int main()
{
            Base *d = new Derived();
            d->func();

            delete d;
            return 0;
}


Output :

This is constant BASE

If const is removed in the base version of func, it prints “This is a Non Constant DERIVED” .

Virtual void func() is actually of a different signature than virtual void func() const. Thus we did’nt override the original, read-only base function. We ended up creating a new virtual function instead of Derived.

If we would have used the keyword “override” in the derived func, then the compiler gives an error message

Error: 'virtual void Derived::func()' marked override, but does not override



The override special identifier means that the compiler will check the base class to see if there is a virtual function with this exact signature.


Final :


C++ also adds the ability to prevent inheriting from classes or simply preventing overriding methods in derived classes. This is done with the special identifier “final”.




Class A final
{
            Virual void f(int);
}

Class B
{
            // No class can override f()
            Virtual void f() final ;
}          


Default and delete specifiers.


Default : A function in the form (=default) is called a defaulted function. The =default ; part instructs the compiler to generate the default implementation for the function. Defaulted functions have two advantages :
a.     They are more efficient than manual implementations
b.     They rid the programmer from the chore of defining those functions manually.

Class Base
{
            Base() = default; // C++11
            Virtual ~Base() = default; // C++11
};


The opposite of defaulted functions is a deleted function:

Int func() = delete;

Deleted functions are useful for preventing object copying, among the rest. Recall that C++ automatically declares a copy constructor and an assignment operator for classes. To disable copying, declare these two special member functions = delete;


Class NonCopyable
{
            NonCopyable (const NonCopyable& ) = delete;
            NonCopyable& operator=(const NonCopyable &) = delete;
}

NonCopyable a;

NonCopyable b (a) ; // Compilation Error, Copy constructor is deleted.


Lambdas functions


C++11 provides the ability to create anonymous functions, called lambda functions. It allows a function to be defined at the point where it’s needed in another expression. It is a function that we can write inline in our code to pass in to another function. We can use lambdas wherever a function object or a functor is expected.

A lambda expression has the form :

[capture] (parameters)->return-type{body}


The [] construct inside a function call’s argument list indicates the beginning of a lambda expression.

Suppose we want to count how many uppercase letters a string contains. Using for_each() to traverse a char array, the following lambda expression determines whether each letter is in uppercase. For every uppercase letter it finds, the lambda expression increments Uppercase, a variable defined outside the lambda expression.’

Int main()
{
            char s[]=”Hello World”;
            int Uppercase = 0; // Variable which will be modified by the lambda.
            for_each(s,s+sizeof(s),[&Uppercase](char c) {
if(isupper(c))
Uppercase++;
});
            cout<<”UpperCase Letters : ”<<Uppercase<<endl;
}

It’s as if you have defined a function whose body is placed inside another function call. The ampersand in [&Uppercase] means that the lambda body gets a reference to Uppercase so it can modify it. Without the ampersand, Uppercase would be passed by value.

Sample lambda function to print the container.

Int main()
{
            Vector<int> v = {1,2,3,4,5};
            For_each(v.begin(),v.end(),[](int n) {cout<<n<<endl;});
           
}

More examples :

Int main()
{
            // 1’st Lambda function
            cout<< [] (int a, int b) { return a*b; } (4,5) <<endl;

            // 2nd Lambda Function
            auto f = [] (int a, int b) {return a*b ; };
            cout<<f(4,5);

            // Explicitly specify the return type of a lambda function.
            cout <<[] (int a)->int { return n*n;  } (5) ;

}

Output:
g++  -std=c++11 lambda.cpp
20

20

Comments

Popular posts from this blog

C++ Guidelines for Multithreaded System

Signalling System #7(SS7) Protocol.

std::shared_ptr