Skip to main content

Posts

Showing posts from 2018

Selection Initialization

  Selection Initialization allows for optional variable initialization within if and switch statements – similar to that used within for statements. for (int a = 0; a < 10; ++a) {    // for body } Here the scope of a is limited to the for the statement. But consider: {    auto a = getval();    if (a < 10) {    // Use a } Here variable a is used only within the if statement but has to be defined outside within its own block if we want to limit its scope. But in C++17 this can be written as: if (auto a = getval(); a < 10) { // Use a } Which follows the same initialization syntax as the for the statement – with the initialization part separated from the selection part by a semicolon (;). This same initialization syntax can similarly be used with the switch statement. Consider: switch (auto ch = getnext(); ch) { // case statements as needed } Which all nicely helps C++ to be more concise, intuitive and cor...

Template Argument Deduction

  Template Argument Deduction is the ability of templated classes to determine the type of the passed arguments for constructors without explicitly stating the type. Before C++17 , to construct an instance of a templated class we had to explicitly state the types of the argument (or use one of the make_xyz support functions). std::pair p(2, 4.5); Here, p is an instance of the class pair and is initialized with values of 2 and 4.5. Or the other method of achieving this would be: auto p = std::make_pair(2, 4.5); Both methods have their drawbacks. Creating “make functions” like std::make_pair is confusing, artificial and inconsistent with how non-template classes are constructed. std::make_pair, std::make_tuple etc are available in the standard library, but for user-defined types it is worse: you have to write your own make_… functions. In C++17,  This requirement for specifying the types for a templated class constructor has been abolished. This means...

Structured Bindings

Returning multiple Values from function C++ 11 vs C++ 17 Returning compound objects Iterating over a compound collection Direct initialization Returning multiple Values from function C++ 11 vs C++ 17 :  C++ 11 (std::tie): std::tuple mytuple() {     char a = 'a';     int i = 123;     bool b = true;     return std::make_tuple(a, i, b);  // packing variable into tuple } To access return value using C++ 11, we would need something like: char a; int i; bool b; std::tie(a, i, b) = mytuple();  // unpacking tuple into variables Where the variables have to be defined before use and the types known in advance. C++ 17 : auto [a, i, b] = mytuple(); Returning compound objects :  This is the easy way to assign the individual parts of a compound type (such as a struct, pair etc) to different variables all in one go – and have the correct types automatically assigned. So let’s have a look at an ...

C++ 17 Introduction

C++17 has brought a lot of features to the C++ language. Let’s dig into three of them that help make coding easier, more concise, intuitive and correct. We’ll begin with Structured Bindings. These were introduced as a means to allow a single definition to define multiple variables with different types. Structured bindings apply to many situations, and we’ll see several cases where they can make code more concise and simpler. Then we’ll see Template Argument Deduction, which allows us to remove template arguments that we’re used to typing, but that we really shouldn’t need to. And we’ll finish with Selection Initialization, which gives us more control about object scoping and lets us define values where they belong.

STL :: std::array<> in c++

Example:          int a[5] = {10,20,30,40,50}; array b; std:copy(std::begin(a),std::end(a),std::begin(b)); for(int x : b) { cout< } cout<<"begin functional iterator : "< for(auto val = b.begin(); val cout<<*val< cout<<"R begin functional iterator : "< for(auto val = b.rbegin(); val cout<<*val< cout<<"AT Function : "< cout<<"at(2) : "< cout<<"front Function : "< cout<<"front() : "< cout<<"back Function : "< cout<<"back() : "< cout<<"[] operator : "< cout<<"b[2] : "<

Containers in c++

SEQUENTIAL CONTAINER Vector (Dynamic Array - Contiguous memory):  O(1): Vectors provide fast (constant time) element insertion and deletion at the end of the vector and Acess. O(n): Slow (linear time) insertion and deletion anywhere else. Insertion and deletion are slow because the operation must move all the elements “down” or “up” by one to make room for the new element or to fill the space left by the deleted element. Like arrays, vectors provide fast (constant time) access to any of their elements. List (Doubly Linked List - Not  Contiguous memory ): O(n): Lists provide slow (linear time) element lookup and access, O(1):  (constant time) insertion and deletion of elements once the relevant position has been found Deque (Doubly Ended Queue - Not Contiguous memory): O(1): (constant time) element access. Like a list, it provides fast (amortized constant time) insertion and deletion at both ends of the sequence. O(1):  (lin...

Part2 : STL Algorithms (Non-Modifying sequence) in c++

3.  Non-Modifying sequence operations:   s earch std::vector vecStack;          int vecNeedle1[] = { 40,50,60,70 };          int vecNeedle2[] = { 20,30,50 }; std::vector ::iterator it_search; // vecStack: 10 20 30 40 50 60 70 80 90 for (int i = 1; i // using default comparison: 1. it_search = std::search ( vecStack.begin() , vecStack.end() , vecNeedle1 , vecNeedle1 + 4 ); if (it_search != vecStack.end()) std::cout << "search: needle1 found at position " << (it_search - vecStack.begin()) << '\n'; else std::cout << "search : needle1 not found\n"; // using predicate comparison: auto val = vecNeedle2 + 3; it_search = std::search ( vecStack.begin() , vecStack.end() , vecNeedle2 , vecNeedle2 + 3 , myfunction ); if (it_search != vecStack.end()) std::cout << "search: needle2 found at position " << (it_search - vecStack.begin()) ...

Part1 : STL Algorithms (Non-Modifying sequence) in c++

Non-Modifying sequence operations : 1.  Non-modifying sequence operations:   _of (CPP 11) std::array all_of_elem = { 3,5,7,11,13,17,19,23 }; 1. if ( std::all_of ( all_of_elem.begin(),   all_of_elem.end() ,  [](int i) {return i % 2; } )) std::cout << "All the elements are odd numbers.\n"; std::array any_of_elem = { 0,1,-1,3,-3,5,-5 }; 2. if ( std::any_of ( any_of_elem.begin() ,  any_of_elem.end() ,  [](int i) {return i )) std::cout << "There are negative elements in the range.\n"; std::array foo = { 1,2,4,8,16,32,64,128 }; 3. if ( std::none_of ( foo.begin() ,  foo.end() ,  [](int i) {return i )) std::cout << "There are no negative elements in the range.\n"; 2.  Non-modifying sequence operations:   find       std::string myints[] = { "Hello", "Hi", "Bye", "ByeBye" }; std::vector myvector(myints, myints + 4); std::vector ::iterator it;...

Sequence Containers: Vectors

Vectors are sequence containers representing arrays that can change in size. Just like arrays, vectors use contiguous storage locations for their elements, which means that their elements can also be accessed using offsets on regular pointers to its elements, and just as efficiently as in arrays. But unlike arrays, their size can change dynamically, with their storage being handled automatically by the container. Container properties Sequence Dynamic array Allocator-aware Example : #include #include int main () { std::vector< int > myvector; for ( int i=1; i<=5; i++) myvector.push_back(i); std::cout << "myvector contains:" ; for (std::vector< int >::iterator it = myvector.begin() ; it != myvector.end(); ++it) std::cout << ' ' << *it; std::cout << '\n' ; return 0; }

Clone Function in C++

class Dog {  public:    virtual Dog* clone() { return (new Dog(*this)); }  // co-variant return type }; class Yellowdog : public Dog {     virtual Yellowdog* clone() { return (new Yellowdog(*this)); } }; void foo(Dog* d) {      // d is a Yellowdog    //Dog* c = new Dog(*d); // c is a Dog    Dog* c = d->clone();    // c is a Yellowdog     //...     //  } int main() {    Yellowdog d;    foo(&d); }

Invoke Virtual Function in Constructor or Destructor

Case 1:  class Dog { public: Dog()  { cout << "Dog Born" << endl; } virtual void bark()  { cout << "Dog barking" << endl; } void SeeCat() { bark();  // first it check bark() in YellowDog else invokes in Dog class } }; class YellowDog : public Dog  { public: YellowDog() { cout << "Yellow Dog Born" << endl; } virtual void bark()  // virtual keyword is optional        { cout << "Yellow barking" << endl; } }; int main() { YellowDog d; d.SeeCat(); } Output:  Dog Born Yellow Dog Born Yellow Dog barking Case 2: why Virtual function in constructor  should be avoided class Dog { public: Dog()  { cout << "Dog Born" << endl; bark();  Since construtor of yellowdog is not yet constructed, so bark of Dog class gets called. } virtual void bark()  { cout << "Do...