Skip to content

Instantly share code, notes, and snippets.

@samehkamaleldin
Created June 13, 2017 16:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samehkamaleldin/deea3ccb85b5e39609f2ded0d04c6a85 to your computer and use it in GitHub Desktop.
Save samehkamaleldin/deea3ccb85b5e39609f2ded0d04c6a85 to your computer and use it in GitHub Desktop.
Demo for some of C++11 capabilities
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <memory>
#include <functional>
using namespace std;
// usage of auto as function return type that depends on template params
template <typename T1, typename T2>
auto sum_types(T1 t1, T2 t2) -> decltype(t1 + t2)
{
return t1+t2;
}
// functions used in tut sections
void fn (char* c ){}
void fn (int n ){}
void disp (char c ){cout << c;}
int sum (int a,int b){return a+b;}
// display section name in stdout
void section(string name){
cout << endl << string(70, '#') << endl;
cout << "# " << name << endl << endl;
}
// struct used in tut sections
struct Foo
{
Foo() { std::cout << "> Foo::Foo \n"; }
~Foo() { std::cout << "> Foo::~Foo\n"; }
void bar() { std::cout << "> Foo::bar \n"; }
};
constexpr double metre(1.0);
constexpr double gram (1.0);
// a user defined litral
constexpr double operator "" _kg(long double q){return q*1000;}
constexpr double operator "" _g (long double q){return q; }
int main(int argc, char** argv)
{
// ---------------------------------------------------------------------------
// Feature : List initialization :
// Summary : initialize an object from braced-init-list :
// Reference : http://en.cppreference.com/w/cpp/language/list_initialization :
// ---------------------------------------------------------------------------
section("List initialization");
//simple initialization of a typed vector using list initialization
vector<int> numbers { 1, 2, 3, 4, 5};
cout << "numbers[02]: " << numbers.at(0) << endl;
vector<string> names { "Ahmed", "Khalid", "Anas", "Heba", "Omar"};
cout << "names[2]: " << names.at(2) << endl;
// string can be initialized as list of chars
string word { 'w', 'o', 'r', 'd'};
cout << "word string: " << word << endl;
// using nested list initialization
map<int,string> ids { {1,"KQ"}, {2,{'R','A'}}, {3,{'M',0x65}} };
// empty list initialization is zero
int zero{};
// ---------------------------------------------------------------------------
// Feature : auto specifier :
// Summary : specify that variable type will be deduced from initializer :
// Reference : http://en.cppreference.com/w/cpp/language/auto :
// ---------------------------------------------------------------------------
section("auto specifier");
// initialize different types using auto
auto name = "Ali";
auto age = 23;
auto alive = true;
cout <<"- " << name << " is " << age << " years old." << endl;
// usage of auto as a function return type
auto res = sum_types(3,12.1);
cout << "- Result is " << res << endl;
// ---------------------------------------------------------------------------
// Feature : Range-based for loops :
// Summary : Executes a for loop over a range :
// Reference : http://en.cppreference.com/w/cpp/language/range-for :
// ---------------------------------------------------------------------------
section("range-based for loop");
// sum pre-defined numbers vector to stdout
int summation{};
for(auto num : numbers)
summation += num;
cout << "- summation of numbers = " << summation << endl;
// loop over list initializer
cout << "- animals: [ ";
for(auto animal : { "monkey", "lion", "elephant"})
cout << animal << " ";
cout << "- ]" << endl;
// ---------------------------------------------------------------------------
// Feature : std :: nullptr - null pointer :
// Summary : There exist implicit conversions from nullptr to null pointer :
// value of any pointer type and any pointer to member type :
// Reference : http://en.cppreference.com/w/cpp/language/nullptr :
// ---------------------------------------------------------------------------
section("std::nullptr");
// [Ref]: http://stackoverflow.com/questions/1282295/what-exactly-is-nullptr \
// #comment1111836_1282345]
//
// Note that NULL is not even guaranteed to be 0. It can be 0L,
// in which case a call to void f(int); void f(char *); will be ambiguous.
// nullptr will always favor the pointer version, and never call the int one.
// Also note that nullptr is convertible to bool
// nullptr will work
fn(nullptr);
// This is ambigous and omits error
// fn(NULL);
// both nullptr and NULL can be converted to bool
bool bvaln = nullptr;
bool bvalN = NULL;
// error as nullptr can't be casted to int
//int ivaln = nullptr;
// will work but will show a warning
// int ivalN = NULL;
// ---------------------------------------------------------------------------
// Feature : std :: shared_ptr - defined in <memory> header :
// Summary : Smart pointer that automatically destroy non-used objects :
// Reference : http://en.cppreference.com/w/cpp/memory/shared_ptr :
// ---------------------------------------------------------------------------
section("std::shared_ptr");
// std::shared_ptr is a smart pointer that retains shared ownership
// of an object through a pointer. Several shared_ptr objects may own
// the same object. The object is destroyed and its memory deallocated
// when either of the following happens:
// 1- the last remaining shared_ptr owning the object is destroyed.
// 2- the last remaining shared_ptr owning the object is assigned
// another pointer via operator= or reset().
// just use it instead of normal pointer to get rid of delete part
char* c_normal(nullptr);
shared_ptr<char> c_shared(nullptr);
// creating two versions of pointer to struct
Foo* p_normal(new Foo);
shared_ptr<Foo> p_shared(new Foo);
// set normal pointer to null [ object not deleted]
cout << "- normal ptr set to null" << endl;
p_normal = nullptr;
cout << "- normal ptr didn't delete the object" << endl;
// set shared pointer to null, destructor called, see output.
cout << "- shared ptr set to null" << endl;
p_shared = nullptr;
cout << "- normal ptr deleted the object [ destructor called ]" << endl;
// ---------------------------------------------------------------------------
// Feature : std :: unique_ptr - defined in <memory> header :
// Summary : Smart pointer that holds a non sharable reference to value :
// Reference : http://en.cppreference.com/w/cpp/memory/unique_ptr :
// ---------------------------------------------------------------------------
section("std::unique_ptr");
// std::unique_ptr is a smart pointer that retains sole ownership of
// an object through a pointer and destroys that object when the unique_ptr
// goes out of scope.
// No two unique_ptr instances can manage the same object.
// The object is destroyed and its memory deallocated when either of
// the following happens:
// 1- unique_ptr managing the object is destroyed
// 2- unique_ptr managing the object is assigned another pointer
// via operator= or reset().
// initialze two unique pointer
unique_ptr<Foo> u_ptr1(new Foo); // uptr1 owns Foo
unique_ptr<Foo> u_ptr2(nullptr);
// check if unqie pointer 1 owns reference
if(u_ptr1)
cout << "- u_ptr1 owns reference" << endl;
else
cout << "- u_ptr1 owns nothing" << endl;
// move ownership to uptr2
u_ptr2 = move(u_ptr1);
cout << "- ownership transfered to u_ptr2" <<endl;
// check if unqie pointer 1 owns reference
if(u_ptr1)
cout << "- u_ptr1 owns reference" << endl;
else
cout << "- u_ptr1 owns nothing" << endl;
if(u_ptr2)
cout << "- u_ptr2 owns reference" << endl;
else
cout << "- u_ptr2 owns nothing" << endl;
// reset u_ptr2;
u_ptr2.reset();
cout << "- reset u_ptr2 object deleted [destructor called]" << endl;
// ---------------------------------------------------------------------------
// Feature : std :: function defined in <functional> header :
// Summary : lass template std::function is a function wrapper :
// Reference : http://en.cppreference.com/w/cpp/language/lambda :
// ---------------------------------------------------------------------------
section("std::function");
// initialize two function objects
function<void(char )> func = disp;
function<int (int,int)> func_sum = sum;
// call the initialized function objects
cout << "- call function [disp]: ";
func('2');
cout << endl;
cout << "- call function [sum]: ";
cout << "- 3 + 4 = " << func_sum(3,4) << endl;
// ---------------------------------------------------------------------------
// Feature : Lambda Functions :
// Summary : Creates anonymous function object that can read objects :
// Reference : http://en.cppreference.com/w/cpp/language/lambda :
// ---------------------------------------------------------------------------
section("lambda functions");
// simplist form of lambda function that do nothing - void(void){}
[](){};
// labmda function can be assigned to std :: function
auto lm_empty_fn = [](){};
// no args lambda fn that show a message
auto lm_msg_fn = [](){cout << "- hello from lambda fn" << endl; };
lm_msg_fn();
// one arg lambda fn that greet a name
auto lm_greet_fn = [](string name_str){cout << "- hi " << name_str << endl; };
lm_greet_fn("Ali");
// lambda function can be call instanteously
[](){cout << "- this is instanteously called lambda fn" << endl; }();
// lambda fn capture variables can be values or references
int a = 8;
[a](int x){return x + a; };
// passing function as capture and call lambda fn instanteously
int lm_sum = [a,func_sum](int b){ return func_sum(a,b); }(9);
cout << "- lambda fn with function as capture: sum is " << lm_sum << endl;
// explicit definition of lambda fn is offered to solve ambigious returns
[]()-> double {return 2.3;};
// ---------------------------------------------------------------------------
// Feature : User Defined Litarals :
// Summary : produce objects of user-defined type by a user-defined suffix :
// Reference : http://en.cppreference.com/w/cpp/language/user_literal :
// ---------------------------------------------------------------------------
section("user defined literals");
// usage of user defined literals [ definition located before main ]
double weight_in_kg = 13.5_kg;
double weight_in_g = 13500.0_g;
if (weight_in_g == weight_in_kg)
cout << "- 13.5 kg == 13500 g" << endl;
// ---------------------------------------------------------------------------
// Feature : User Defined Litarals :
// Summary : produce objects of user-defined type by a user-defined suffix :
// Reference : http://en.cppreference.com/w/cpp/language/user_literal :
// ---------------------------------------------------------------------------
section("static_assert");
// static assert is assert in compile time, that if condition is true nothing
// happens otherwise it omits the specified error messages
const int big_num1 = 300;
const int big_num2 = 67;
// this won't omit compiler error as it's true
static_assert( big_num1 > 100 , "this number is not odd");
// the next will omit a comiler error
//static_assert( big_num2 > 100 , "this number is not odd");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment