C and C++

C/C++ Learning

My Small TODO list for basic C learning

TODO - Make a basic C++ learning page - keep this one for interesting technical features - eventually add/create the advanced stuff too.

  • Class declaration
  • Instance data members and functions
  • class data members and functions
  • inheritance virtual functions etc.
  • Define compiling, linking etc.
  • bibliography

GSoap

Simple Soap String assignment

    // iSoap is the main soap structure object created before
    std::string *name = soap_new_std__string(iSoap);
    std::string  someName = "Mr Name";
    name->assign(someName);

Vector style assignment

    std::vector<ParameterType *> &parameters = DEREF(SomeMessage::soap_new_std__vectorTemplateOfPointerToSomeMessage__CurParameterType(iSoap));
    parameters.emplace_back(someParameterType);

GSoap and namespace conflicts

GSoap file generation - splitting files

soapcpp2 -f

This option splits the serialization source code saved to soapC.c and soapC.cpp files into multiple soapC_NNN files as specified by the numeric parameter. This option alleviates compilation issues with very large source code files.

For example:

soapcpp2 -f40 file.h

This generates multiple soapC_NNN.cpp files each with 40 serializers, with NNN counting from 001 onward.

The value of this option must be larger or equal to 10.

GTest

TEST, TEST_F, TEST_P

These are different use cases for GTest Stack Overflow question about the diffs with nice explanation and the docs Link to TEST_F docs

Custom Failure Message in Assertions

When failing a test you can add a custom message like this:

  EXPECT_EQ(expected, actual) << "Expected not equal to actual...";

Celero benchmarking

Windows compiling C code

Printing a C String

  #include<stdio.h>

  void main()
  {
    char name[]="siva";
    printf("%s\n",name);
    printf("%c\n",*name);
  }

Boost libraries

Installing

  • Install the package: sudo apt install libboost-all-dev
  • Otherwise it can be included from other dependencies in your projects

Date and Time stuff

  if(today.someTime() == tomorrow.someTime()){ // blah }
  // Instantiate - h, m, s, fs
  boost::posix_time::time_duration departureTime(1, 2, 3, 4);
  // Instantiate from a string
  boost::gregorian::date d(boost::gregorian::from_string("2020-03-05"));
  • Default date time or duration value:
    • not_a_date_time is the default value and can check with .is_not_a_date_time() function.
 boost::date_time::not_a_date_time

Boost String manipulation

String Splitting using boost (among others)

C++ examples

auto&& auto - auto type deduction in range based for loops

References and Pointers examples

TODO - provide some basic examples here, the rest is moved to it's own section TODO -> example from Julien with pointers and addresses…

String Manipulation

Printing integers, appending to strings

#include <iostream>
#include <string>
#include <sstream>
 
std::string toString(auto &i){
   std::stringstream ss;
   ss << i;
 
   return ss.str();
}
 
int main()
{
    int i = 17;
    std::string s = "C++" + toString(i);
 
    std::cout << s << '\n';
 
    return 0;
}

Includes

Difference between include "" and include <>

On most compilers, using the "" first checks your local directory, and if it doesn't find a match then moves on to check the system paths. Using <> starts the search with system headers.

Typical rule of thumb is "" for your own headers, <> for system includes.

cin to read input

// Read a line of text, including spaces etc
getline(cin, theName);

// Read some text, stopping at first whitespace
cin >> theName;

string::assign vs assignment operator "="

Both are basically the same, the only time that .assign() gives an advantage is if you specify the exact size of the string to be assigned.

NB - could be nicer syntax wise for assignment with pointers

// Assign vs = (result is the same + speed is the same)
std::string name; std::string temp = "blah";

name.assign(temp); // same as name = temp;

// example with pointer
std::string *name; name->assign(temp);
name = &temp; // Maybe a little less easy to read???

// Example where assign is quicker
test2.assign("Hello again", sizeof("Hello again") - 1); // don't copy the null terminator!
// or
test2.assign("Hello again", 11);

Named Parameters

C++ functions have default parameter values but not named parameters. Below are two examples of how to implement a solution for this:

Enums and pointers to enums

In the C-style/pre-C++11 style enums here's an example of working with a GSoap pointer to an enum value:

    MyEnumType *getMeAValueOfEnumType(struct soap *iSoap) {

    enum MyEnumType *typeCode = nullptr;

    typeCode = BlahSchemaWebService::soap_new_MyEnumType(iSoap);
    // This is the interesting bit - ref the typeCode value and assign it the value of your enum value.
    *typeCode = MyEnumType::BLUE;

    return typeCode;

}

Templates - (notes from effective C++)

Basic introduction

Templates are also called Generic programming so some parallels with java from that point of view (although this is based on my current basic understanding).

https://learning.oreilly.com/library/view/effective-c-third/0321334876/ch07.html

  • object-oriented programming revolves around explicit interfaces and runtime polymorphism
  • Template program focuses more on implicit interfaces and compile time polymorphism
    • when you see something inside a templated function, you can see it must respect an implicit interface based on what methods etc. it calls.
    • Instantiating function templates with different template parameters leads to different functions being called - compile time polymorphism.

Class vs typename

  • For declaring template parameters, NO DIFFERENCE
  • For declaring variables etc. inside the template, there are two cases: types dependent on template parameter and independent types
    • typename should be used to identify only nested dependent type names by adding it before the declaration to clarify.

Vectors, Maps etc

Map

http://www.cplusplus.com/reference/map/map/find/

// it is an Iterator
it = mymap.find('b');
if (it != mymap.end())
  mymap.erase (it);

Map with struct as a key

If using a map with a key which is a struct or complex key, there needs to be a hash function provided also to handle key collisions

Vectors

Vector initialize

  std::vector<std::string> v = {"foo", "bar"};
  • Declaring a vector will initialize an empty vector so can check this with v.empty();

  • The void reserve(size_type numberOfElements) function can be used when we know in advance the minimum number of elements in the vector we want to create. https://www.geeksforgeeks.org/using-stdvectorreserve-whenever-possible/. It will reserve that amount of memory to avoid reallocating up to that number of elements which can improve performance.

    int sizeOfVector = 5000;
  
    vector<int> v1, v2;
  
    // Reserve space in v2
    v2.reserve(sizeOfVector);

Vector basic operations

  • front() - get the item from the front of the vector
  • back() - get the item from the back of the vector
  • emplace_back()/push_back() - adding items to the back of the vector - STD way to add to the vector
    • General rule: Favour emplace_back over push_back (see below for more details)
  • empty() check if the vector is empty
#include <iostream>
#include <vector>

int main () {

    std::vector<int> myvector;

    myvector.emplace_back(78);
    myvector.emplace_back(16);

    // now front equals 78, and back 16

    myvector.front() -= myvector.back();

    std::cout << "myvector.front() is now " << myvector.front() << '\n';

    return 0;
}

Vector size - size_type

A vector size is not an int - it's a size_type. The type of the size of an **std::vector** is **std::vector::size_type**

Be careful with this kind of thing when iterating.

The vector size is:

  • NOT int
  • NOT unsigned_int
  • NOT size_t

TODO - add to this once I discuss with someone more knowledgeable

Vector searching

Finding elements in a vector in different ways - https://thispointer.com/c-how-to-find-an-element-in-vector-and-get-its-index/

  • std::find_if - can take a custom function to use for matching
  • C++11 has range based for loop for(auto && blah: blahs)…

TODO - ask/learn more about both approaches

Vector (and containers in general) removing things in-place

Containers - emplace_back vs push_back

emplace_back is really useful: void emplace_back(Args&&…);

Instead of taking a value_type it takes a variadic list of arguments, so that means that you can now perfectly forward the arguments and construct directly an object into a container without a temporary object at all.

That's useful because no matter how much cleverness RVO and move semantic bring to the table there are still complicated cases where a push_back is likely to make unnecessary copies (or move). For example, with the traditional insert() function of a std::map, you have to create a temporary, which will then be copied into a std::pair<Key, Value>, which will then be copied into the map

std::map<int, Complicated> m;
int anInt = 4;
double aDouble = 5.0;
std::string aString = "C++";

// cross your finger so that the optimizer is really good
m.insert(std::make_pair(4, Complicated(anInt, aDouble, aString))); 

// should be easier for the optimizer
m.emplace(4, anInt, aDouble, aString);

References and Pointers

  • References are like the difference between primitives and objects in Java
  • int a = 4; int& b = a;
    • if a changes value b does too since it's like another label for a
  • Can't change the assignment of b once applied.
  • Also reference can't be null, must be an object
  • To pass a pointer to something expecting a ref, we can just deref the pointer
    • e.g. Blah &blah = *somePointerBlah;
  • used a lot for passing function params.
    • Allows to modify external objects within a function IMPORTANT - C++ passes parameters by VALUE only so ref allows passing args which can be used to modify things outside the function

Articles

Constructors and Destructors - default, delete and explicit keywords

Default

Delete

class X {

      // ...
      X& operator=(const X&) = delete;  // Disallow copying
      X(const X&) = delete;

};

Explicit

  • Should be used with single argument constructors to avoid any implicit conversions
  • Implicit conversion could be using the constructor as a conversion constructor to transform an input to another function into an object of that class type (e.g. in the Deitel book (10.13 explicit Constructors and Conversion Operators)
  • Example shown below:
class Account {
  public:
    explicit Account(std::string accountName) : name{accountName} {
      // empty body
    }
};

Initialization

#include <iostream>

int x = 0; struct S {

      int n = ++x;
      S() { }                 // uses default member initializer
      S(int arg) : n(arg) { } // uses member initializer

};

int main() {

      std::cout << x << '\n'; // prints 0
      S s1;
      std::cout << x << '\n'; // prints 1 (default initializer ran)
      S s2(7);
      std::cout << x << '\n'; // prints 1 (default initializer did not run)
      std::cout << s2.n << '\n'; // prints 7 - value initialized into n

}
  • BIG NB - A Reference member variable MUST be initialized in the constructor intializer list
          class MyClass {
           public:
             MyClass(int, AnotherClass& a); // NO CAN'T DO THIS
             MyClass(int iAmount, AnotherClass& a): amount(iAmount), myRefMember(a){} // MUST do like this

           private:
            int amount;
            AnotherClass& myRefMember;
           };
  • This is the type of error you'll see if not
    • "'MyClass::myRefMember' must be initialized in constructor base/member initializer list".

Virtual Destructor

Move Semantics - C++11

  • Nice explanation here in the answers - https://stackoverflow.com/questions/3106110/what-is-move-semantics
    • C++11 uses the rvalue reference which allows the possibility to "move a resource from one object to another without copying" i.e. avoiding copy constructor
      • Very basic explanation and apparently lots more to learn from this one….

C++ Stack and Heap

  • Heap
    • anything from a "new" - e.g. new int(5); i.e. dynamic memory
    • If using "new" you MUST HAVE A corresponding "delete"
  • Stack
    • anything directly created

Pragma directive

https://www.google.com/search?client=ubuntu&channel=fs&q=%23pragma+once&ie=utf-8&oe=utf-8

If you want something to be included only once in a compilation use the following in the beginning of the file as a preprocessor directive:

#pragma once

Macros

Static

Static in C++ means that the code is executed ONCE per application lifecycle. This could be tricky for example a function local static might LOOK like it gets executed more than once but only the first execution is taken into account. Putting inside a function is a way of having a predictable initialization time for the var.

Constant tips from Nico

  • Never put something as static with a declaration in the header file - it will get duplicated into the including code files so there will be a duplicate e.g. string in every file
  • Instead use extern for the declaration and initialize in the .cpp file.

Need to understand more on this….

Standard Template Library

Callbacks and lambdas

Idea for me to use for the logging messages:

Forward Declarations

Used to declare something before it is defined. extern keyword required if something declared OUTSIDE the same file. I think this can be useful also for making recompilation more efficient… TODO - expand on this point.

  • https://stackoverflow.com/questions/4757565/what-are-forward-declarations-in-c
    • How forward-declarations can significantly reduce build times -
      • You can get the declaration of a function into your current .cpp or .h file by #including the header that already contains a declaration of the function. However, this can slow down your compile, especially if you #include a header into a .h instead of .cpp of your program, as everything that #includes the .h you're writing would end up #include'ing all the headers you wrote #includes for too. Suddenly, the compiler has #included pages and pages of code that it needs to compile even when you only wanted to use one or two functions. To avoid this, you can use a forward-declaration and just type the declaration of the function yourself at the top of the file. If you're only using a few functions, this can really make your compiles quicker compared to always #including the header. For really large projects, the difference could be an hour or more of compile time bought down to a few minutes.
#include <iostream>

int add(int x, int y); // forward declaration of add() (using a function prototype)

int main() {

      std::cout << "The sum of 3 and 4 is: " << add(3, 4) << '\n'; // this works because we forward declared add() above
      return 0;
}

// even though the body of add() isn't defined until here 
int add(int x, int y){
      return x + y;
}

Functions

It's a feature introduced in C++11 - it means that you want to use the compiler-generated version of that function, so you don't need to specify a body.

Building C++ projects

Compiler information

CMake

This seems like a very good way of handling complex makefiles

  • TODO - understand public/private linkage to avoid forcing re-linking for every change, only for public ones
  • A nice explanation - https://cmake.org/pipermail/cmake/2016-May/063400.html
    • Private - A links B as private to say that nothing in the public API of A uses B
    • Interface - A links B as interface to say that nothing in the implementation of A uses B, but B is used in the public API of A.
    • Public - A links B as public to say that A uses B both in the public API of A and in the implementation of A.
    • In terms of cpp and hpp (my take on it so may need corrections :))
      • Private - A uses B only in the .cpp files
      • Interface - A uses B only in the .hpp files
      • Public - A uses B in both .hpp and .cpp files

Quick summary

  • CMakeLists.txt file contains details of folders and files to build
  • § cmake . - builds the makefile
  • § make - executes makefile to create binary etc.
  • § ./hello - execute your file

Build also with Ninja


List of C++ Learning Topics initial

  • References
  • auto auto&&
  • rvalue and lvalue
  • Copy constructor along with example from Julien
  • Data members
    • "Always intialized in order of declaration in class definition regardless of order in initialization list" what does this mean
  • Syntax of constructor - void print(int i): a1(i)…..
  • cpp vs hpp - where does the class {} declaration go etc.
  • friend functions
    • member/non-member function
    • friend class
  • inheritance example
    • constructor + destructor + defaults e.g. non-arg constructor
    • copy constructor
    • access control
  • p54 - object conversions - pointers + access violations
  • templates
  • bibliography
    • Obj oriented prog using C++ 2ed Ira Pohl
    • Thinking in C++ 2ed Bruce Eckel
    • C++ Programming language Bjarne Stroustrup

C++ Advanced Course Notes

  • sudo apt install g++ make cmake vim valgrind

Topics I need to know better

  • Macros
  • assert vs static_assert
  • Templates
  • Overloading operators
  • Unique, shared pointers in boost - see where they're used in real projects code and slides 64 onwards - also in the exercise 3
  • RAII also
  • Virtual functions implementation and vtab
  • Name mangling - way of handling overloaded method names in linker
  • Friend functions and classes
  • extern - different compilation unit not static
  • namespaces - using vs using namespace + rules like not having "using namespace" in a header file
  • Anonymous namespaces and the typedefs for C++11 vs old C/C++03 style typedef
  • STL overview + look at Container memory allocation scheme - allocator
  • Containers - deque look at it double ended queue, binary tree in a vector impl (i- children are 2*i, 2*i+1)
  • Function operators

NB - lab mentions CMake Cache removal -> could this be useful for us too?

Course Overview

  • 1. Basic C++ concepts and mechanisms
    • Objects, types, and classes
    • Template basics
    • Ownership smart pointers (C++11)
  • 2. Advanced C++ mechanisms
    • Exceptions
    • Templates and overloading
    • RTTI and ISO C++ casts
    • Multiple inheritance
    • Namespaces
  • 3. The Standard Template Library (STL)
    • Containers and iterators
    • Function-objects
    • C++11 lambdas
    • Algorithms, strings, and IO streams
    • Exception safety

Notes

  • C++ compile - error doesn't stop compilation but stop any code being generated at the end
  • auto is a C keyword but is redundant -> e.g. in a for loop - auto int i; and int i; are the same - the variable scope is limited to the block where it is declared.
  • using auto keyword -> compiler relies only on the expression to determine the type for the variable.

  • for loops
for (string elem : vs) cout << elem <<  ; // NB - could end up with a copy here
for (string& elem : vs) elem = "";          // Better to use a reference
for (auto elem : vs) cout << elem <<  ;
for (auto& elem : vs) elem = "";
for (auto&& elem : vs) elem = "hello";      // Most efficient way of doing it -> will adapt to all situations but for now I have no idea how it works - need to do the C++ libraries course :)

References

  • used a lot for passing function params.

Allows to modify external objects within a function IMPORTANT - C++ passes parameters by VALUE only so ref allows passing args which can be used to modify things outside the function

see slide 14

  • example of refs vs pointers for an integer swap function…
  • const should be used as much as possible - e.g. if passing a ref to a function where we are sure we don't want to modify the obj
 void someFunction( const MyClass &object) {
    // Do stuff using a const ref since you do not want to modify object
 }

Slide 15

  • references behave as non null constant pointers -> cannot point to NULL with ref, once ref points to some object it must remain pointed there.

Like a java final object - can modify the values of the object via the ref but cannot change the object pointed to.

Slide 16 NBNBNB VERY IMPORTANT

  • Explains why we need refs vs pointers in C++ -> ambiguity of the & with pointers

Slide 21

  • interesting user defined implicit conversion -> r + 2 can be converted to r + Rational(2) by compiler due to having an available one-arg constructor

Slide 25

  • Shows where variables are defined + live (e.g. heap/stack)

Slide 26 - Constructors

  • should favour the "member intialization list" -
    • C::C() : A(), b() {}
    • Instead of putting constructor intialization calls inside the {} body
    • Some calls e.g. call to parent class constructor can ONLY be done there
    • Also reference assignment/init can ONLY be done in member initialization list

Destructors

  • IOStreams - nearly last things to be destroyed by destructors -> e.g. cin, cout - allow them to be available as long as possible

Slide 31

  • Order of declaration + instantiation in member intialization list is REALLY IMPORTANT, especially for inheritance etc.
class B : public A1, public A2 { // A1 then A2
private:
string _s; // initialized first
int _dim; // initialized second
public:
B(const string& s) : _dim(_s.size()), A1(_dim), _s(s) // WRONG - A1 called before _dim is intialized
{...}
// CORRECT - respect the order and use input to constructor instead of mixing with member vars (i.e. s instead of _s)
B(const string& s) : A1(s.size(), _s(s), _dim(s.size())

Slide 36

  • RVO - return value optimisation -> for a simple copy the C++11 compiler onwards will allocate the memory directly at caller level to avoid doing a temp object which could be expensive (e.g. a = b does a simple copy - in effect it's like a call to a function with a temp object created then the value returned and copied into the a variable. Now the temp object is not created, instead a is allocated directly)

Working with pointers and references

  • accessing properties using reference - dog.name
  • accessing properties using pointer - dog->name

Returning a reference:

  return *this;

*Slide 41 * Shows use of default and delete to indicate default functions and to prevent using functions like destructor etc.

Better than defining a class with private constructor, copy constructor etc.

Template Basics

  • Slide 47 Templates
    • template function is a SET of functions - one for every single possible type
    • template class is a SET of classes
    • The mechanisms for functions and classes are different

Function Template

Example

template <typename T>
const T& Min(const T& a, const T& b) {
    return a < b ? a : b;
}
  • Using function template
    • parameterized overloaded function:
  int x, y, z; z = Min(x, y);
  • explicit instantiation (if effective params cannot be deduced): int x; double m = Min(x, 5.7);

TODO add my Template notes here…

Smart Pointers

  • unique pointers
  • shared pointers
  • weak pointers

TODO -> Review slides 60-80 for shared pointers since I missed this bit


Exceptions

  • link to std::exceptions - https://en.cppreference.com/w/cpp/error/exception
  • Slide 85 - exceptions
    • destructor is automatic once an exception stops being propagated
    • C and C++ -> cannot call main() directly - forbidden by language but in any case would miss the necessary context to run
  • Example of catch BY REFERENCE -> this is preferred way since it avoids a copy of the exception object
catch (Stack::exception& e) {
  cout << e.what();
}

Rethrowing an exception

Exceptions can be rethrown if not handled by a particular piece of code by using "throw;" i.e. without any argument.

try {
  mayThrowMyErr();
} catch (myErr &err) {
  err.append("Add to my message here");
  throw; // this throws the same object
  throw err; // this throws a copy of the object -> might lose the appended messages etc. if using inheritance - you will lose derived-class-specific data
}

From above link:

Rethrowing an Exception

If a catch block cannot handle the particular exception it has caught , you can rethrow the exception. The rethrow expression > (throw with no argument) causes the originally thrown object to be rethrown.

Because the exception has already been caught at the scope in which the rethrow expression occurs, it is rethrown out to the next > dynamically enclosing try block. Therefore, it cannot be handled by catch blocks at the scope in which the rethrow expression > occurred. Any catch blocks following the dynamically enclosing try block have an opportunity to catch the exception.

The rethrow expression can be caught by any catch whose argument matches the argument of the exception originally thrown.

  • Slide 92
  // Top level exception class - defined in ISO standard
  class exception {
       public:
          virtual const char *what() const noexcept;
          };
  • what() should return a string describing the message
    • NB - char instead of std::string because a std::string could throw an exception.
    • last const means it will not modify the containing class
    • noexcept means it doesn't throw an exception (C++11 onwards, C++03 used throw() i.e. an empty list of thrown exceptions)
  • around slide 96 -
    • no finally clause in C++
    • destructor is more or less equiv to finalize() in java
    • BUT destructor guaranteed to be called in C++.
    • In java finalize() only called if GC decides it.
  • Slide 99
    • In a constructor can add a try + catch but it's not pretty

B(const string& s) try : A(s) {
  // constructor code
} catch(Exc_A) {
  // clean up after exception
  // IMPLICIT THROW ADDED by C++ compiler so you don't think the object is correctly created,
  // the catch only allows you to cleanup
  throw;
}

TODO - look more at this

  • Slide 100
  • Slide 132
    • TypeInfo - size increases with number of virtual functions and dynamic type identification.
    • Reduced use in today's programs due to template use - can even use compiler option if sure not to use it
  • Slide 137
    • Details of dynamic_cast and static_cast

Templates Continued

  • Slide 104
    • C++ / other static type languages, class template instances are not implicitly convertible - e.g. set of French people is implicitly part of set of humans but not for C++

This is necessary to preserve static type checking - e.g. refer to a set of French as a set of Humans but without being able to add an English person via the set of Humans i.e. a Set is not implicitly convertible to Set

  • Slide 107

Shows an example of our exercise from yesterday where we wanted to have a parent-child conversion via template parameter

  • Slide 108

vtab example to explain why member templates can never be virtual one vtab per class (need to understand more about vtab and virtual functions)

Namespaces - never put "using namespace" in the header file since it will end up including namespace and any includes within….can be very big

  • Slide 157

Backward compatibility and ISO standards


#include <utility> 
-> C++ way to include a standard library 
#include <cstdio> 
and not 
#include <stdio.h> 
- makes ANSI C functions available in the std namespace
  • Slide 160

Anonymous namespace and the using BLAH = std::string; that we use to have a nice way to refer to stuff NB - removes need for typedef std::string BLAH that was used in C

  • Slide 165 - 168

Namespaces and function hiding + inheritance - worth reviewing

NB - access control in C++ is "Software engineering" control so you can always "cheat" by working around private etc. e.g. in the namespaces you can abuse "using A::f" in a child class to expose private methods of A as public.

  • Slide 173
    • Also the overloading of java doesn't exist in the same way for C++ -
      • see the example where f(int) of child class B hides f(char) of parent class A unless you have using A::f in the child class B
      • This is because compiler sees "f" as a property -
        • i.e. same in A and B so B is taken - unless you have "using" statement to bring the def down to class B level.

STL Library stuff

  • Slide 181 STL library stuff - template container with Allocator

  • Slide 186

    • Collections Algorithms of STL - no idea about objects it manipulates.
    • Results in super fast efficient code but no safety -
      • e.g. pointer to BEGIN and END are expected to be part of same collection, if not then undefined behaviour.

STL uses no inheritance and has no object orientation…

  • Slide 189
    • STL Containers from C++11 on can initialize like C aggregate ->
       vector<int> v = {2, 3, 4, 5};
    
    • Also for example, maps can use this
  • Slide 192
    • Collections example showing map using iterator with ->first and ->second to have key and value.
  • Slide 193
    • Container value_types must have copy operations to allow copying value into element of the container.
  • Slide 198
    • STL Algorithms don't ever change the size of a container (even algos which modify elements of container) - due to using simple pointers as iterators.
  • Slide 202
    • Function objects - functor - class that defines operator()
            class is_gt_4 {
            public:
              bool operator()(int i) {return i > 4;}
            };

  • Slide 206
    • Lambda calculus - 1936 alonso church prof of turing
  • Slides 206-220
    • lambda examples ->
    • NB I'm using C++11 so some C++14 features are not available.
  • Slide 223
    • Insert algorithms to add new elements with special iterators.
    • Work around the fact that the algorithm will not modify size of a container.
  • Slide 225
    • Remove algorithms -> DONT remove anything - instead will return a pointer to the end of a new sublist.
    • Then can use this to call for example
      li.erase(xxx, li.end)
    

    which really does remove the elements.

    • See the slide for example.

UBUNTU Suspend notes

Interview stuff