Friday, March 18, 2016

C++ Misc



#include <iostream>
std::cout << "Hello World!" << std::endl;

absl::optional
std::optional
The auto keyword specifies that the type of the variable being declared will be automatically deduced from its initializer.

for (const auto& [key, value] : my_map)
for (const auto& entry : my_map)

Assume a bare auto will make a copy
Always specify auto& or const auto& unless a copy is desired
Prefer const auto& over auto& unless you need to modify the underlying value
Prefer auto* or const auto* to make pointers explicit in the code

Starting in C++17, objects are created "in place" when possible
objects are not copied until after they are first given a name

Structured bindings
auto [iter, was_inserted] = m.insert({key, data});

If you declare a function constexpr, that function can be called inside of constant expressions.


for (const std::string& word : words) 

[=, &x, &y](int i) mutable -> return_type { /* code */ }
[]: Nothing is captured.
[x]: x is captured by value (i.e., a copy is made).
[x, &y]: x is captured by value, y is captured by reference.
[=, &y]: y is captured by reference, any other local variable used is captured by value.
[&, x]: x is captured by value, any other local variable used is captured by reference.


Keeping the Copy Constructor and Copy assignment operator as private in the class.
Inherit a Dummy class with a private copy constructor and a private copy assignment operator.
Using Deleted copy constructor and copy assignment operator: Above two ways are quite complex, C++11 has come up with a simpler solution i.e. just delete the copy constructor and assignment operator.
    Base(const Base& temp_obj) = delete;
    Base& operator=(const Base& temp_obj) = delete;



global variables should be trivially destructible

The using declaration should be inside a namespace.
using statements should be fully qualified.
Avoid deeply nested namespaces, and never introduce sub-namespaces with common 
If you use output parameters, they should usually go after input parameters.
prefer using return values over output parameters.
An advantage of enum class is that conversion to/from integers requires explicit conversion
The order of dynamic initialization of globals in different translation units is completely unspecified.
In modern C++, you should rarely call new and delete directly
operator+ on strings is needlessly inefficient, use absl::StrCat instead

Structural elements of a lambda expression

  1. capture clause (Also known as the lambda-introducer in the C++ specification.)

  2. parameter list Optional. (Also known as the lambda declarator)

  3. mutable specification Optional.

  4. exception-specification Optional.

  5. trailing-return-type Optional.

  6. lambda body.

A lambda can introduce new variables in its body (in C++14), and it can also access, or capture, variables from the surrounding scope. A lambda begins with the capture clause (lambda-introducer in the Standard syntax), which specifies which variables are captured, and whether the capture is by value or by reference. Variables that have the ampersand (&) prefix are accessed by reference and variables that do not have it are accessed by value.

An empty capture clause, [ ], indicates that the body of the lambda expression accesses no variables in the enclosing scope.



we can get the memory address of a variable by using the & operator
cout << &food; // Outputs the memory address of food (0x6dfed4)

pointer however, is a variable that stores the memory address as its value.

A pointer variable points to a data type (like int or string) of the same type, and is created with the * operator. The address of the variable you're working with is assigned to the pointer:

by using the * operator (the dereference operator):

Note that the * sign can be confusing here, as it does two different things in our code:

  • When used in declaration (string* ptr), it creates a pointer variable.
  • When not used in declaration, it act as a dereference operator.
string* ptr = &food;    // Pointer declaration

// Reference: Output the memory address of food with the pointer (0x6dfed4)
cout << ptr << "\n";

// Dereference: Output the value of food with the pointer (Pizza)
cout << *ptr << "\n";

// Change the value of the pointer
*ptr = "Hamburger";

1
2
3
myvar = 25;
foo = &myvar;
bar = myvar;


The values contained in each variable after the execution of this are shown in the following diagram:



First, we have assigned the value 25 to myvar (a variable whose address in memory we assumed to be 1776).

The second statement assigns foo the address of myvar, which we have assumed to be 1776.


It is important to clearly differentiate that foo refers to the value 1776, while *foo (with an asterisk * preceding the identifier) refers to the value stored at address 1776, which in this case is 25. Notice the difference of including or not including the dereference operator (I have added an explanatory comment of how each of these two expressions could be read):

1
2
baz = foo;   // baz equal to foo (1776)
baz = *foo;  // baz equal to value pointed to by foo (25)  

Pointers and arrays

The concept of arrays is related to that of pointers. In fact, arrays work very much like pointers to their first elements, and, actually, an array can always be implicitly converted to the pointer of the proper type. For example, consider these two declarations:

1
2
int myarray [20];
int * mypointer;


The following assignment operation would be valid:

 
mypointer = myarray;


After that, mypointer and myarray would be equivalent and would have very similar properties. The main difference being that mypointer can be assigned a different address, whereas myarray can never be assigned anything, and will always represent the same block of 20 elements of type int.

Pointers can be initialized either to the address of a variable (such as in the case above), or to the value of another pointer (or array):


1
2
3
int myvar;
int *foo = &myvar;
int *bar = foo;
*p++   // same as *(p++): increment pointer, and dereference unincremented address
*++p   // same as *(++p): increment pointer, and dereference incremented address
++*p   // same as ++(*p): dereference pointer, and increment the value it points to
(*p)++ // dereference pointer, and post-increment the value it points to 


A typical -but not so simple- statement involving these operators is:

 
*p++ = *q++;


Because ++ has a higher precedence than *, both p and q are incremented, but because both increment operators (++) are used as postfix and not prefix, the value assigned to *p is *q before both p and q are incremented. And then both are incremented. It would be roughly equivalent to:

1
2
3
*p = *q;
++p;
++q;

int&& a means "a" is an r-value reference. && is normally only used to declare a parameter of a function. And it only takes an r-value expression.

Simply put, an r-value is a value that doesn't have a memory address. E.g. the number 6, and character 'v' are both r-values. int a, a is an l-value, however (a+2) is an r-value.

void foo(int&& a)
{
   //Some magical code...
}
int main()
{
   int b;
   foo(b);       //Error. An rValue reference cannot be pointed to a lValue.
   foo(5);       //Compiles with no error.
   foo(b+3);     //Compiles with no error.
   int&& c = b;  //Error. An rValue reference cannot be pointed to a lValue.
   int&& d = 5;  //Compiles with no error.
}

For example  inserts to std::vector (or in fact any array creation) will not cost huge amount of allocs/copies anymore.   

In C++ working with  references become prevalent since they are safer alternative to pointers and very importantly new language features such as automatic call of constructors or  destructors (automatic cleanup) or operators worked only with them.    


Pointers: A pointer is a variable that holds memory address of another variable. A pointer needs to be dereferenced with * operator to access the memory location it points to. 

References : A reference variable is an alias, that is, another name for an already existing variable. A reference, like a pointer, is also implemented by storing the address of an object. 
A reference can be thought of as a constant pointer (not to be confused with a pointer to a constant value!) with automatic indirection, i.e the compiler will apply the operator for you. 

int i = 3; 

// A pointer to variable i (or stores
// address of i)
int *ptr = &i; 

// A reference (or alias) for i.
int &ref = i; 
int &p;
 p=a;    // it is incorrect as we should declare and initialize references at single step.
4. Reassignment: A pointer can be re-assigned. This property is useful for implementation of data structures like linked list, tree, etc. 

5. On the other hand, a reference cannot be re-assigned, and must be assigned at initialization.

6. Memory Address: A pointer has its own memory address and size on the stack whereas a reference shares the same memory address (with the original variable) but also takes up some space on the stack.

7. NULL value: Pointer can be assigned NULL directly, whereas reference cannot. The constraints associated with references (no NULL, no reassignment) ensure that the underlying operations do not run into exception situation.



8. Indirection: You can have pointers to pointers offering extra levels of indirection. Whereas references only offer one level of indirection.I.e, 

In Pointers,
int a = 10;
int *p;
int **q;  //it is valid.
p = &a;
q = &p;

Whereas in references,

int &p = a;
int &&q = p; //it is reference to reference, so it is an error.

9. Arithmetic operations: Various arithmetic operations can be performed on pointers whereas there is no such thing called Reference Arithmetic.(but you can take the address of an object pointed by a reference and do pointer arithmetics on it as in &obj + 5).) 

  • Use references 
    • In function parameters and return types.
  • Use pointers: 
    • Use pointers if pointer arithmetic or passing NULL-pointer is needed. For example for arrays (Note that array access is implemented using pointer arithmetic).
    • To implement data structures like linked list, tree, etc and their algorithms because to point different cell, we have to use the concept of pointers.
  • References are used to refer an existing variable in another name whereas pointers are used to store address of variable.

  • References cannot have a null value assigned but pointer can.

  • A reference variable can be referenced by pass by value whereas a pointer can be referenced but pass by reference.

  • A reference must be initialized on declaration while it is not necessary in case of pointer.

  • A reference shares the same memory address with the original variable but also takes up some space on the stack whereas a pointer has its own memory address and size on the stack.

Pointers and references are equivalent, except:

  1. A reference is a name constant for an address. You need to initialize the reference during declaration.
    int & iRef;   // Error: 'iRef' declared as reference but not initialized
    Once a reference is established to a variable, you cannot change the reference to reference another variable.
  2. To get the value pointed to by a pointer, you need to use the dereferencing operator * (e.g., if pNumber is a int pointer, *pNumber returns the value pointed to by pNumber. It is called dereferencing or indirection). To assign an address of a variable into a pointer, you need to use the address-of operator & (e.g., pNumber = &number).
    On the other hand, referencing and dereferencing are done on the references implicitly. For example, if refNumber is a reference (alias) to another int variable, refNumber returns the value of the variable. No explicit dereferencing operator * should be used. Furthermore, to assign an address of a variable to a reference variable, no address-of operator & is needed.
Pass-by-Value

In C/C++, by default, arguments are passed into functions by value (except arrays which is treated as pointers). That is, a clone copy of the argument is made and passed into the function. Changes to the clone copy inside the function has no effect to the original argument in the caller. In other words, the called function has no access to the variables in the caller

Pass-by-Reference with Pointer Arguments
Pass-by-Reference with Reference Arguments

Instead of passing pointers into function, you could also pass references into function, to avoid the clumsy syntax of referencing and dereferencing.


That is because a temporary can not bind to a non-const reference.

double &m = a;

a is of type int and is being converted to double. So a temporary is created. Same is the case for user-defined types as well.

Foo &obj = Foo(); // You will see the same error message.
Just make it a constant: const Foo &obj = Foo(); 

Move semantics allows you to avoid unnecessary copies when working with temporary objects that are about to evaporate, and whose resources can safely be taken from that temporary object and used by another.

An lvalue is an expression whose address can be taken, a locator value--essentially, an lvalue provides a (semi)permanent piece of memory. You can make assignments to lvalues

Rvalues are--well, rvalues are not lvalues. An expression is an rvalue if it results in a temporary object.

An rvalue reference is a reference that will bind only to a temporary object.

The intuition here is that you cannot use a "mutable" reference because, if you did, you'd be able to modify some object that is about to disappear, and that would be dangerous. Notice, by the way, that holding on to a const reference to a temporary object ensures that the temporary object isn't immediately destructed. This is a nice guarantee of C++, but it is still a temporary object, so you don't want to modify it.

In C++11, however, there's a new kind of reference, an "rvalue reference", that will let you bind a mutable reference to an rvalue, but not an lvalue. In other words, rvalue references are perfect for detecting if a value is temporary object or not. Rvalue references use the && syntax instead of just &, and can be const and non-const, just like lvalue references, although you'll rarely see a const rvalue reference (as we'll see, mutable references are kind of the point):

1
2
const string&& name = getName(); // ok
string&& name = getName(); // also ok - praise be!


the auto keyword declares a variable whose type is deduced from the initialization expression in its declaration


iterator find (const key_type& k);
// Create an iterator of map
std::map<std::string, int>::iterator it;
// Find the element with key 'hat'
it = wordMap.find("hat");
// Check if element exists in map or not
if (it != wordMap.end())
// Access the Key from iterator
std::string key = it->first;
// Access the Value from iterator
int value = it->second;



The macro NULL is an implementation-defined null pointer constant, which may be


an integral constant expression rvalue of integer type that evaluates to zero

(until C++11)

an integer literal with value zero, or a prvalue of type std::nullptr_t


Initialization using the initializer list
    int myint{ 123 };
    double mydouble{ 456.78 };

#include <map>
    // empty map container
    map<int, int> gquiz1;
  
    // insert elements in random order
    gquiz1.insert(pair<int, int>(1, 40));
    map<int, int>::iterator itr;
    for (itr = gquiz1.begin(); itr != gquiz1.end(); ++itr) {
        cout << '\t' << itr->first
             << '\t' << itr->second << '\n';
    }
http://www.geeksforgeeks.org/dangling-void-null-wild-pointers/
A pointer pointing to a memory location that has been deleted (or freed) is called dangling pointer. There are three different ways where Pointer acts as dangling pointer
  1. De-allocation of memory
int main()
{
    int *ptr = (int *)malloc(sizeof(int));
 
    // After below free call, ptr becomes a
    // dangling pointer
    free(ptr);
     
    // No more a dangling pointer
    ptr = NULL;
}
Function Call
// The pointer pointing to local variable becomes
// dangling when local variable is static.
#include<stdio.h>
 
int *fun()
{
    // x is local variable and goes out of
    // scope after an execution of fun() is
    // over.
    int x = 5;
 
    return &x;
}
Output:
A garbage Address
The above problem doesn’t appear (or p doesn’t become dangling) if x is a static variable.
// The pointer pointing to local variable doesn't
// become dangling when local variable is static.
#include<stdio.h>
 
int *fun()
{
    // x now has scope throughout the program
    static int x = 5;
 
    return &x;
}
Variable goes out of scope
void main()
{
   int *ptr;
   .....
   .....
   {
       int ch;
       ptr = &ch;
   } 
   .....   
   // Here ptr is dangling pointer
}
Void pointer is a specific pointer type – void * – a pointer that points to some data location in storage, which doesn’t have any specific type. Void refers to the type. Basically the type of data that it points to is can be any. If we assign address of char data type to void pointer it will become char Pointer, if int data type then int pointer and so on. Any pointer type is convertible to a void pointer hence it can point to any value.
Important Points
  1. void pointers cannot be dereferenced. It can however be done using typecasting the void pointer
  2. Pointer arithmetic is not possible on pointers of void due to lack of concrete value and thus size.
int main()
{
    int x = 4;
    float y = 5.5;
     
    //A void pointer
    void *ptr;
    ptr = &x;
 
    // (int*)ptr - does type casting of void
    // *((int*)ptr) dereferences the typecasted
    // void pointer variable.
    printf("Integer variable is = %d", *( (int*) ptr) );
 
    // void pointer is now float
    ptr = &y;
    printf("\nFloat variable is= %f", *( (float*) ptr) );
 
    return 0;
}

NULL Pointer is a pointer which is pointing to nothing. In case, if we don’t have address to be assigned to a pointer, then we can simply use NULL.
#include <stdio.h>
int main()
{
    // Null Pointer
    int *ptr = NULL;
     
    printf("The value of ptr is %u", ptr);
    return 0;
}

The value of ptr is 0
Important Points
  1. NULL vs Uninitialized pointer – An uninitialized pointer stores an undefined value. A null pointer stores a defined value, but one that is defined by the environment to not be a valid address for any member or object.
  2. NULL vs Void Pointer – Null pointer is a value, while void pointer is a type
  3. A pointer which has not been initialized to anything (not even NULL) is known as wild pointer. The pointer may be initialized to a non-NULL garbage value that may not be a valid address.
    int main()
    {
        int *p;  /* wild pointer */
     
        int x = 10;
     
        // p is not a wild pointer now
        p = &x;
     
        return 0;
    }
On a high level both of them are wrappers over theread() system call, just syntactic sugar. The only visible difference is that scanf() has to explicitly declare the input type, whereas cin has the redirection operation overloaded using templates. This does not seem like a good enough reason for a performance hit of 5x.
It turns out that iostream makes use of stdio‘s buffering system. So, cin wastes time synchronizing itself with the underlying C-library’s stdio buffer, so that calls to bothscanf()and cin can be interleaved.
The good thing is that libstdc++ provides an option to turn off synchronization of all the iostream standard streams with their corresponding standard C streams using
std::ios::sync_with_stdio(false);
  • Like with all things, there is a caveat here. With synchronization turned off, using cin and scanf() together will result in an undefined mess.
  • With synchronization turned off, the above results indicate that cin is 8-10% faster than scanf(). This is probably because scanf() interprets the format arguments at runtime and makes use of variable number of arguments, whereas cin does this at compile time.
http://www.geeksforgeeks.org/endl-vs-n/
cout << endl  : Inserts a new line and flushes the stream

cout << "\n"  : Only inserts a new line.
cout << endl;
can be said equivalent to
cout << ‘\n’ << flush;
As a conclusion, cout << “\n” seems performance wise better than cout << endl; unless flushing of stream is required.

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts