Different people have different ideas of what is simple.

— Bjarne Stroustrup

Contents

Versions

Cpp variants

As C was apparently not Good Enough, C++ developers lack the temperament to leave things well-enough alone. They’re constantly re-imagining the language as broken and trying to fix it. Every couple of years there is a major change in how things are done.

Wikipedia’s enumeration of C++ versions is ok. Here is a list of more exotic species. Here is a whole history of the genus. Here is my little catalog.

C++98

AKA - ISO/IEC 14882:1998

Main Features
  • RTTI (dynamic_cast typeid)

  • covariant return types

  • cast operators

  • mutable

  • bool

  • declarations in conditions

  • template instantiations

  • member templates

  • export

Library Features
  • locales

  • bitset

  • valarray

  • auto_ptr (now deprecated)

  • templatized string

  • iostream

  • complex

Standard Library Features
  • algorithms

  • iterators

  • function objects

C++03

AKA - ISO/IEC 14882:2003

Mostly bug fixes and subtle implementation standardization details.

Features
  • Value initialization

C++11

  • AKA - ISO/IEC 14882:2011

  • AKA - C++0x

C++14

AKA
  • ISO/IEC 14882:2014

  • C++1y

Descriptions
Main Features
  • Function return type deduction

  • Alternate type deduction on declaration[5]

  • Relaxed constexpr restrictions

  • Variable templates

  • Aggregate member initialization

  • Binary literals

  • Digit separators

  • Generic lambdas

  • Lambda capture expressions

Standard Library Features
  • Shared mutexes and locking

  • Heterogeneous lookup in associative containers

  • Standard user-defined literals

  • Tuple addressing via type

  • Smaller library features

C++17

Published: 2017-12-01

Here is the latest official C++ 2017 Standard - 1622 pages!

AKA
  • ISO/IEC 14882:2017

  • C++1z

C++20

As one might expect, this one is still being worked on in 2019.

Preprocessor

Tag brackets mean look for this file in the directory where all the standard libraries are stored.

#include <iostream>

Double quotes mean the same as tag brackets or the current directory if the specified file is found in it.

#include "main.hpp"

Namespace

The following line is an example of how kludgey C++ can be:

using namespace std;

I find this command to be awkward. It is cryptic, not part of your train of thought when trying to get something to work and, unfortunately, hardly ever unnecessary. This line simply must be included to activate the correct name space for certain important libraries. There may be others but <iostream> and <string> are definitely some that need this command.

Without it you need something like this.

std::cout<<"This is suboptimal.";

Although this is an annoying requirement because most of the time it is used mechanically in the case shown above, the namespace mechanism is a C++ feature that allows better organization and protection of program elements.

Starting with C++2011 the using keyword can have a different meaning. It is used to set an "alias". As far as I can tell this works much like a typedef. Maybe something like this.

typedef std::map<std::string,int> mymaptype;
using mymaptype= std::map<std::string,int>; // Same thing basically.

Apparently it’s better to go with the second, newer, style. One reason is that typedef doesn’t handle templatization well. There may be other reasons but it is at least good to know what you’re looking at when you find code like this.

Comment Styling

In C, the comments are this bizarre syntax:

/* This is a classic C style comment. */

In C++ that is acceptable but there is another style that has a starting designator and runs to the end of the line. Like this:

// This is a C++ comment.
x++ // The beginning of this line is not a comment but this is.

Style

For style tips in general, you could do worse than to emulate these guys. (Do they not host it themselves anymore?)

Here’s another.

Note that OpenCV also has a style guide. They prefer names ending in .cpp and .hpp. And 4 spaces, no tabs.

Variable Types

As with C, all variables must be explicitly declared before using. The point of this relates to C and C++ and their very explicit use of memory management.

Constants

Like C, make a variable immutable with the const keyword. Hmm, a "read-only variable", like the C++ error messages say, is an oxymoron, right? Still, it is a part of the C++ religion to pray to the const gods at every opportunity.

This is simple in the simple cases. But there is all kinds of mischief that can arise from this. The most absurd to me is the mutable keyword which can make const declarations, uh, less const.

Wait a moment… This just in… I’ve received word that C++11 has introduced a new keyword into the language — don’t act all surprised — the word is constexpr. As far as I can tell, const can be assigned a value (that thence remains constant) at runtime, but constexpr is carved in stone at compile time. I would imagine that things like this are a teensy bit more resource efficient.

constexpr double PI= 3.14159265358979323846;

The normal const could be applied to things like this.

int main(const int argc, char** argv){  ...

Here the number of arguments can be different depending on how the program is executed, but once the value is set, argc will be locked for the duration of the execution.

It turns out that constexpr can be used with functions too. This is limited to simply return (maybe with some awful ternary operator tricks). But C++14 expands the potential of constexpr functions. I’m thinking of these like old C preprocessor macros that do simple things during compilation so that the precomputed answers are injected into to the source code. But C++ tries hard to bring that sort of thing into the language proper. The limitation with constexpr functions is that all arguments must also be constexpr for it to be effective. If they are not, it just pushes it out to normal runtime execution. Another fact to understand that helps explain it, is that such pre-computations at compile time will likely make the compiling process take longer.

Type Details

Note
Actually in some situations the Cpp11 auto keyword (not to be confused with the K&R C auto compiler hinting) allows the types of variables to be automatically deduced from context. Some more information and examples.

bool Exclusive to C++!

Boolean

1byte

keywords true or false, or integers 1 or 0

char

Character or small integer.

1byte

signed: -128 to 127 unsigned: 0 to 255

short int (short)

Short Integer.

2bytes

signed: -32768 to 32767 unsigned: 0 to 65535

int

Integer.

4bytes

signed: -2147483648 to 2147483647 unsigned: 0 to 4294967295

long int (long)

Long integer.

4bytes

signed: -2147483648 to 2147483647 unsigned: 0 to 4294967295

float

Floating point number.

4bytes

+/- 3.4e +/- 38 (\~7 digits)

double

Double precision float

8bytes

+/- 1.7e +/- 308 (\~15 digits)

long double

Long double float.

8bytes

+/- 1.7e +/- 308 (\~15 digits)

wchar_t

Wide character.

2 / 4 bytes

1 wide character

Note that C++ is more strict about type casting that C.

Variable definitions in C generally must be at the beginning of a block whereas in C++ they can be anywhere in the block.

C++ provides a way to get a runtime check of what kind of type a variable is. This is done with the typedef function and is useful when variables can be any of several types or objects.

Enum

C enum values are always sized int whereas in C++ they are a distinct type and can have different sized values. This defines a new user type DOW.

enum DOW {Sun,Mon,Tue,Wed,Thu,Fri,Sat};

You can do a lot in the definition. Here the type declares a variable (casual) and sets it.

enum DOW {Sun,Mon,Tue,Wed,Thu,Fri,Sat} casual=Fri;

Some people believe that enums should be named as singular nouns and not plural. Although enums may define a collection of possibilities for, say, problem_types, the possibility will just be a problem_type when actually used.

Enum Scoping

In the old C++98 days if you defined an enum and then wanted to use one of its member’s names for something else, that was a problem. For example if you had already defined a DOW enum as above, and then wanted this, that would lead to confusion.

auto Wed= Wedding();

The solution is to create a "class enum" or, as it is known by its less obvious but more correct name, "scoped enum".

enum class DOW {Sun,Mon,Tue,Wed,Thu,Fri,Sat};

Now you can have a star named Sun which won’t get confused with the day of the week enum member.

Implicit Conversions

  • integer to float = OK

  • char to float = OK

  • float to int = OK (truncated obviously)

  • float to char = silently does the wrong thing

Strings

Classic C Style - cstring

Because C++ is based on C, the spartan techniques of old school C work in C++ too. Note that as in C, double quotes signify strings and single quotes are characters.

#include <iostream>
using namespace std;
int main(){
    char my_char_array[4]= {'a', 'b', 'c','\0'};
    cout << my_char_array << endl;
    char unterminated_rubbish[3]= {'x', 'y', 'z'};
    cout << unterminated_rubbish << endl;
    char fixed_len_msg[]= "Really just an array of simple chars.";
    cout << fixed_len_msg << endl;
    return 0;
}

Note that in the example that unterminated_rubbish is just that. With no termination, functions like cout just keep reading memory until it finds a null. It can pick up all kinds of wacky stuff. In my example I found that it printed the abc string too until it found its termination byte.

abc
xyzabc
Really just an array of simple chars.

So think carefully about using this style of C character array strings with C++ functions. However the cstring library can be used with this kind of string and it does work fine if done carefully.

#include <iostream>
#include <cstring>
using namespace std;
int main(){
    char fixed_len_msg[13]= "Ok C string.";
    char msg_copy[13];
    strcpy(msg_copy,fixed_len_msg);
    cout << fixed_len_msg << endl;
    cout << strlen(fixed_len_msg) << endl;
    cout << strcmp(msg_copy,fixed_len_msg) << endl;
    cout << msg_copy << endl;
    cout << strcat(msg_copy,fixed_len_msg) << endl;
    cout << strcmp(msg_copy,fixed_len_msg) << endl; // <0 if A<B, >0 if A>B
    cout << *strchr(msg_copy,'C') << endl; // returns ptr to pos of char 'C'.
    cout << *strstr(msg_copy,"Ok") << endl; // returns ptr to pos of string "Ok".
    printf("The length is: %04d\n",strlen(msg_copy));
    return 0;
}

That code produced this output.

Ok C string.
12
0
Ok C string.
Ok C string.Ok C string.
-28
C
O
The length is: 0024

string Class

In C++ the string class is a more elaborate mechanism for working with strings. Strings are generally used like this:

#include <iostream>
#include <string>
using namespace std;
int main(){
    string mystring("Defined in constructor.");
    string somedots(4,'.');
    cout << mystring << endl;
    mystring= "Redefined by assignment.";
    cout << mystring << somedots << endl;
    cout << somedots + "and concatenation." << endl;
    cout << mystring.size() << endl;
    return 0;
}

Produces this.

Defined in constructor.
Redefined by assignment.....
....and concatenation.
24

Note that because it is a class (string) it can be initialized like a new object as an initialization function parameter. Subsequent redefinitions use the overloaded = operator to simulate the way normal people would expect a programming language to work.

Methods for string class include:

  • S.length()

  • S.size()

  • S.empty() - 0 if not empty and a 1 (or maybe some other nonzero) when it is indeed empty.

  • S.append("suffix") - A lot like +.

  • S.assign()

  • S.replace()

  • S.find(str2,pos) - Find the first occurrence of an entire second string’s position within string S. The pos parameter is to start looking only after a certain position; 0 is search all.

  • S.rfind() - Like find but finding the last occurrence. And pos is the maximum character to search. A value greater than or equal to S.length() searches the whole thing.

  • S.find_first_of() - Searches a string S for any characters supplied. Position limits are like find().

  • S.find_last_of() - Same as find_first_of() but the like rfind().

  • S.find_first_not_of() - Invert the match checking of find_first_of.

  • S.find_last_not_of() - Inverted matching of find_last_of.

  • S.compare()

  • S.erase() - Erases particular characters specified by 1. position and length, 2. iterator position, or 3. starting and ending iterators.

  • S.push_back(char) - Append a character.

  • S.reserve()

  • S.substr()

For find operations, if the target is not found, it will return string::npos which on my system produced 18446744073709551615 (2^64-1). Checking the return value for this is how you check if something was found.

Fancy Strings For People Using Weird Letters

Apparently C++11 introduced the char16_t which is a double byte char (the ordinary stuff a classic std::string is made of).

char     c{ 'a' };
char     cu8{ u8'a' }; // cu8 == c
wchar_t  wc{ L'a' };
char16_t c16{ u'a' };
char32_t c32{ U'a' };

Initialization and Definition

When I started programming with C++ in ancient times, if you wanted x to be 3 you said int x=3; sort of like you do with classic C. The problem with this in C++ is that it can be slightly ambiguous, or at least inconsistent. Note how I’m basically using a couple of ways to simply define things in the following code.

#include <iostream>
using namespace std;

class Fancy {
   public:
      Fancy(){x=0;}
      Fancy(int N){x=N;}
      Fancy operator=(int X) { x= X; return *this; }
   private:
      int x;
};

int main(){
    Fancy f(99);
    f= 33;
    Fancy g= Fancy(100);
    return 0;
}

Also note that if you tried to initialize a special type with an empty argument list like Fancy f(); you’d have basically just declared a function. Today with C++11 and beyond there is a thing called "uniform initialization". This uses braces and although it has its problems, it is a bit more consistent.

This would basically look like this:

Fancy h{101};

It can also be used to initialize more complex objects.

std::vector<int> v{9,8,7};

Input And Output

C uses scanf and printf for input and output. C++ can use these but idiomatic C++ programs use a different mechanism not available in C.

cin>>
cout<<

These are available from include #iostream. You probably also want to turn on using namespace std; to cut down on trivial scope chatter. These are really not exactly functions but more like named pipes (in the std namespace) which get data sent in and out of them (<< and >> are overloaded operators normally used for bit shifting).

The >> operator is the "extraction" operator and reads input "items" which are expected to be delimited by whitespace (space, newline, tab).

if (fileStream.is_open())
    while (fileStream.good()) {
        string word;
        fileStream >> word;
        // Do something with "word"
        }

Here is a complete output ("insertion" operator) example:

#include <string>
#include <iostream>
using namespace std;
int main () {
  string thestr("String objects can be output like so.");
  cout << thestr << endl;
  return 0;
}

The cout doesn’t just dump a \n; it also performs cout.flush().

Here are some good notes on C++ IO.

cin and getline

It seems that cin is good for reading space delimited fields one field at a time (or something like that), but it doesn’t read whole lines.

#include <iostream>
#include <string>
int main() {
    std::string myLine;
    std::cout<<"Enter the whole line: ";
    std::getline(std::cin, myLine);
    std::cout<<"Your line is: "<<myLine<<"\n";
    return 0;
}

Here is an example of reading each character of standard input into a string.

#include <iostream>
#include <string>
using namespace std;
int main () {
  string docstr;
  while (!cin.eof()) { docstr.push_back(cin.get()); }
  docstr.pop_back(); // Ditch the last thing read, the End Of File FF.
  cout << docstr;
  cout << docstr.length() << endl;
  return 0;
}

iomanip - Manipulators

Instead of old C stdio.h printf formatting, C++ prefers you to use something called a "manipulator". The classic endl is such a thing. For more complicated manipulations, you’ll need to use <iomanip>.

Depending on how wild you get you may want to preserve stream formatting settings before mucking them up and then restoring them when you’re done. To save a copy of the current settings, use something like this.

// Include these...
#include <iostream>
#include <iomanip>
// Save existing settings.
ios:fmtflags preserved_flags= cout.flags();
int preserved_precision= cout.precision();
// Do some crazy stuff.

// Restore settings with this.
cout.flags(preserved_flags);
cout.precision(preserved_precision);

To pad with leading zeros (or any character) use something like this.

cout << setfill('0') << setw(10) << mynum << endl;

Here is a lesson about manipulators.

#include <iostream>
#include <iomanip>
int main () {
    std::cout<<std::setw(15)<<"Padded 15"
             <<std::setw(20)<<"Padded 20"<<std::endl;
    return 0; }

Besides the normal setw, there is also setfill, setprecision, and setbase. In Cpp11 there are some manipulators for money and time. (See here.)

stringstream

#include <iostream>
#include <string>
#include <sstream>

int main () {
    std::string stringifiednumber;
    float mynumber = 0;
    std::cout << "Enter number: ";
    std::getline (std::cin,stringifiednumber);
    std::stringstream(stringifiednumber) >> mynumber;
    std::cout<<"Plus one would be: "<<++mynumber<<"\n";
    return 0;
}

File Operations

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main(){
    string line;
    // Create output stream for writing in append mode.
    ofstream f2write ("input.txt", ios::app);
    if (f2write.is_open()) {
        f2write << "\nThe End.\n";
        f2write.close();
    }
    else
        cout << "Unable to open file for writing";
    // Create input stream for reading.
    ifstream f2read ("input.txt");
    // The file is opened at ifstream creation.
    if (f2read.is_open()) {
        while ( getline (f2read,line) ){ cout << line << '\n'; }
        f2read.close();
    }
    else
        cout << "Unable to open file for reading";
    return 0;
}

Memory

Some C++ specific keywords, new and delete, help with memory allocation and deallocation issues.

Functions

In C it is good practice to prototype functions (describe their input and output before using them).

Unlike C, in C++ functions can be overloaded. This means that their meaning can be redefined.

Also C++ can use functions inside of structures. This is not common but it hints at the more C++ way of organizing functionality, classes, discussed in the next section.

Unlike C, C++ allows the program to define default values for function arguments.

Deleted Functions

Sometimes you might see something like this.

class Something : public Something_base {
public:
   definitely_floats(float x) {return x*2;}
   definitely_floats(int x) = delete;
};

This is a C++11 style which is similar (but superior I’m told) to declaring a private function and then just neglecting to define it. This is to prevent it from being used. This way, by being explicit about it, you can get more sensible compiler errors.

Increment Operators

Prefix operators (e.g. ++var) increment the value and then return a reference.

Postfix operators (e.g. var++) create a copy of the variable, increment the value, then return the copied, unincremented value.

Also C++ has += and other such operators as found in Python.

Inline Functions

C++ discourages the use of preprocessor complexity. Instead, the idiomatic C++ way to do preprocessor functions is with the keyword inline.

Control Flow

if-else
if (x>=y) {dothis();}
else if (x<y) {dothis();}
else {dothis();} // Optional.
case
int choice=1;
switch (choice) {
    case (0) : cout<<"no"<<endl;  break;
    case (1) : cout<<"yes"<<endl; break;
    default : cout<<"huh?"<<endl;
}
for
for (int i=0; i<10; i++) {
    std::cout<<i<<endl;
}
for with implicit type casting
#include <cstddef>
for (std::size_t i=0; i<10; i++) {

There is also a newish for more like Python or Bash.

for ( declaration : range ) statement;
while
while (conditional) { do_stuff(); // Keep it up! }
do { do_stuff(); } while (conditional); // Make sure at least one happens.

Both break, to exit the loop immediately, and continue, to conclude the current loop body execution and go on to the next, are valid.

To get an infinite loop that needs a break to get out of (or not) here are options.

for (;;){... }
while(1){... }

Pointers

int I=20, *pI;
pI= &I; // Pointer to I is the address location of I.
cout << *pI; // Dereference returning value pointed to by pI.

One thing to note about C++ is that using 0 and NULL used to be ok to refer to a null pointer. This is no longer polite. This can cause problems when overloaded functions can’t figure out if you mean an integer (as in 0) or a null pointer. For null pointers, the correct modern C++ way is to use nullptr.

Smart Pointers

A smart pointer was first part of C++98. In C++11, there are now three more types of smart pointers. These have pretty much all of the same functionality as normal pointers but with a lot of baggage to try to help keep things under control.

  • std::auto_ptr - Deprecated — only consider using for legacy requirements.

  • std::unique_ptr - Replaces auto_ptr but with correct copying. Actually, copying is not even a thing with this pointer but move is. If you could copy it, it wouldn’t be unique, would it? It is a move-only type. Converting to std::shared_ptr is ok. Destruction normally uses delete but can also use a custom destructor.

  • std::shared_ptr - Has reference counting for multiple ptrs with the same target. Double the size of raw pointers to store a pointer to a reference count (actually the "control block" where the reference count and other things are stored which makes it more than double). Must be atomic or bad things happen. Also creating multiple shared pointers for the same object is a bad idea; there will be multiple reference count accounting and the deletes will be more or less random. You can copy shared pointers for mostly the same intended (but correctly functioning) effect. Shared pointers have no normal array features, e.g. no operator[]; generally use std::array or std::vector instead.

  • std::weak_ptr - Like shared, but doesn’t increase reference count. Needs to check if object is still there. Usually created from std::shared_ptr. Valid when a something like a shared_ptr is needed but it may dangle. More can be found about when this might be applicable here.

auto mysharedptr= std::make_shared<MyType>(); // Ref count is 1.
std::weak_ptr<MyType> myweakptr(mysharedptr); // Ref count is 1.
mysharedptr= nullptr;                         // Ref count is 0. The MyType destroyed.
if (myweakptr.expired()) { // Do something... // Points to nothing so expired.

Note that the function is framed as expired() because testing for it being still valid is tenuous; this is because at any moment (e.g. between you checking and doing something about it) it could expire. You can get that behavior only by creating a std::shared_ptr from the weak one. That is an atomic check and grab which will be null if the std::weak_ptr has expired. Do that like this.

std::shared_ptr<MyType> ptrcheck= myweakptr.lock();

Smart Pointer Creation

To allocate smart pointers you could do something like this.

std::unique_ptr<MyClass> my_unique_ptr(new MyClass);

This makes you have to repeat the type and apparently has other problems. The modern recommended way is to do it like this with special functions designed for the purpose.

auto my_unique_ptr(std::make_unique<MyClass>());

Works with make_shared<Type>() too. (make_unique is C++14 and make_shared is C++11).

These functions work better almost always but may have problems if you need to have custom memory management, like your own operator new and operator delete. But that’s super exotic.

References

References are a feature specific to C++ not found in C. Although the subtleties get complex, the greatest utility of references is simply as a way to pass by reference to functions easier. You can still move things around by pointers if you want but references often allow function calls to be less complicated.

  • In Unix terms, I think of pointers as symlinks and references as hard links. The reference is the object accessed differently, not a pointer to an address that may not contain anything.

  • You can also think of a reference as a constant pointer.

  • Pointers are variables that contain memory addresses while references are additional definitions of compiler tracked objects. (The compiler thinks: "Ah, he’s calling x another thing, y, now too.") Of course the compiler can use the same machinery it uses for pointers for this but references can be implemented more efficiently. That’s up to the compiler.

  • References point to objects (whose address a reference shares), while pointers can point to other pointers, ad infinitum.

  • References can not point to other references. (You are forbidden from specifying any such thing, however, if a compiler causes this to happen, say by some weird template instantiation or auto usage or messy typedef, the two references "collapse" using a baroque heuristic.)

  • References can (should) not normally be NULL.

  • References can not iterate using pointer arithmetic.

  • Pointers need to be dereferenced with *, or -> for class members, while references can be dereferenced with . like the referent ("automatic indirection").

Simple Demonstration Of References
#include <iostream>
using namespace std;

// Function with reference parameters.
void one2theother(int &from, int &to) { from--; to++; }
// Function with reference parameters returning a reference.
int &add2together(int &a, int &b) {
    int s; int &r2s=s; r2s= a+b; return r2s; }

int main () {
    int var= 10; int var2= 99;
    int &ref2var= var;
    cout << var << endl      // 10
       << ref2var << endl;   // 10
    ref2var++;
    cout << var << endl      // 11
       << ref2var << endl;   // 11
    var++;
    cout << var << endl      // 12
       << ref2var << endl;   // 12
    one2theother(var,var2);  // Function using references.
    cout << var << endl      // 11
       << ref2var << endl    // 11
       << var2 << endl;      // 100
    cout << add2together(var,var2) << endl; // 111
    return 0;
}

Here is a lot of expertise on the topic for those who really need it.

Rvalue References

Newish C++ is littered with double ampersands as in this parameter definition: MyClass&& x. What the heck is that all about? These are "rvalue references". They are also sometimes called "forwarding references".

An rvalue (see values below) reference is mostly used to bind to temporary objects in order to make them more efficient. They also are useful in "move semantics" and "perfect forwarding" which is about juggling items in memory in a sensible way. They can only bind to objects for which moving in plausible.

This apparently is very useful in template code. In template argument deduction there is a concept called "universal references" which is subtly different but uses the same double ampersand. There something like MyClass&& x could refer to a reference or the real object. These arcane subtleties are discussed here. One general rule is that if there will be magical type deductions as with auto or templates, then the && syntax is a universal reference and not necessarily constrained to an rvalue reference. An important implication is that if you use this kind of trick it’s best not to make the universal reference an argument of overloaded functions. This will tend to try to fit the universal reference before fitting what you really wanted it to fit. Ah, automagical — not always so auto or magic.

If you want to make sure these automagical helper monkeys stay in their cages, you can use the explicit keyword which will prevent implicit conversions and copy initializations. Another way to get universal references to behave "explicitly" in your overloaded functions is to use what’s called "tag dispatch" this is where you add bogus arguments so that the function signature is certain to be the correct match.

Values

In C++, especially the modern species, you see the term "lvalue" and "rvalue" pop up a lot. For some reason it is taken for granted that programmers will instinctively know the etymology of these words. I used to think it was "left value" and "right value" as in which side of the equals sign something like x=3; was on. Wikipedia hints, misleadingly I suspect, that lvalue might have something to do with "location".

lvalue properties
  • Traditionally on the left side of an assignment expression.

  • Its address can (usually) be taken.

  • Designates a function or object (usually).

rvalue properties
  • Traditionally on the right side of an assignment expression.

  • Its address can (usually) not be taken.

  • A temporary object or some other kind of value not associated with an object.

This lvalue and rvalue stuff is bad enough to have to think about but modern C++ spirals out of control with three more types.

There are now the following value types. * rvalue - Fun fact: rvalue references returned from functions are themselves rvalues. * lvalue - A "parameter" is always an lvalue. void f(MyClass&& x); the parameter x is still an lvalue even if its type says otherwise. * glvalue - Generalized lvalue, a subspecies of lvalue. * xvalue - Expiring value referring to an object whose resources can be moved because it is nearing its destruction. Perhaps as function return values which are exotic reference things which necessarily will be gone after the return. Something like that. * prvalue - Pure rvalue. Like an xvalue but for simple rvalue non-reference things (themselves).

The horrendous gory details can be explored here.

Move and Forward

The functions (function templates to be exact) std::move and std::forward are interesting in that they do not move or forward (respectively) anything. They are compile time mechanisms for elaborate casting which I feel is the most important thing to understand about them — they do nothing at runtime. It seems that move should have been named something like rvalue_cast. Since rvalue objects are the kind that can be properly moved, the std::move function does provide a running start to that actual functionality.

So what do they do? The std::move casts an argument to an rvalue. The std::forward does the exact same thing but only in limited cases.

If you’re fighting with these mechanics, also keep in mind std::remove_reference which strips the l- or r-valueness.

Move requests on const objects are silently transformed to copy operations (losing any efficiency you may have envisioned).

The std::forward function (template) is mostly used in a function template taking a universal reference parameter that will be forwarded to another function. Since arguments are lvalues, if you have an argument that needs to stay an rvalue and get passed on as such, that’s what std::forward is good (known) for. The condition it checks for is if the argument it is looking at is an rvalue. If not, then it just passes it on without any exotic casts. In theory the std::move function could always be replaced by the more comprehensive std::forward. But subtle differences in "clarity", I suppose, have produced both.

Classes

C++ features organization by classes.

Special member functions are the ones that C++ can create implicitly.

Table 1. Special Member Functions

default constructor

X()

destructor

~X() // C++11 forces noexcept

copy assignment

void operator=(X &src)

copy constructor

X(X &src)

move constructor

X(X&& src) // new in C++11

move assignment

X& operator=(X&& src) // new in C++11

In C++11 there is a way to actively produce these special member functions which, under some circumstances (not ever used, etc), don’t get auto-generated. This uses the keyword default.

X(const X&) = default; // Normal copy ctor is fine, make one for X.
X& operator=(const X&) = default; // Normal copy assignment ctor is ok too.
X(X&&) = default; // Normal moving.
X& operator=(X&&) = default; // Normal moving assignment.

This might just be easier to comprehend as a reminder that these things can (and now will) autogenerate.

Example of Using Classes
// cxe- Wed May 12 12:22:10 PDT 2004
// This is a test of using inheritance to create a containable class (or array
// in this example) of heterogenous objects. The goal will be to store 2
// classes in the same array in such a way that they are usable.

#include <string>
#include <iostream>
using namespace std;

class Number {  // This is the base class.
   public:
      Number() {}
      virtual void show() { cout << "No base class data!" << endl; }
   private:
}; // end class Number

class Roman: public Number {
   public:
      Roman operator=(string p) { pretium= p; return *this; }
      void show() { cout << "Roman:" << pretium << endl; }
   private:
      string pretium;
}; // end class Roman

class Arabic: public Number {
   public:
      Arabic operator=(int v) { value= v; return *this; }
      void show() { cout << "Arabic:" << value << endl; }
   private:
      int value;
}; // end class Arabic

int main() {
   Number z; //can't do anything with z
   Arabic a; a= 19;
   Roman  r; r= "XIX";
   cout << "Objects as themselves, no container ----------" << endl;
   z.show(); a.show(); r.show();

   Number n[3]; // Array of base class objects
   n[0]= z; n[1]= a; n[2]= r;
   cout << "Objects in container of baseclass ----------" << endl;
   n[0].show(); n[1].show(); n[2].show();

   Number *p_n[3]; // Array of pointers to Numbers
   p_n[0]= &z; p_n[1]= &a; p_n[2]= &r;
   cout << "Objects in container of baseclass pointers ----------" << endl;
   p_n[0]->show(); p_n[1]->show(); p_n[2]->show();

   return 0;
} // end main

This outputs the following.

Objects as themselves, no container ----------
No base class data!
Arabic:19
Roman:XIX
Objects in container of baseclass ----------
No base class data!
No base class data!
No base class data!
Objects in container of baseclass pointers ----------
No base class data!
Arabic:19
Roman:XIX

Note that the default access is private so by listing them before public, you can save that keyword. I think it’s better to just be explicit though.

Declarations will often need the class namespace. This looks like this.

retVar ClassName::somefunction(int x,int y);

The protected access control specifier means that the item specified is treated like public by derived classes and private from unrelated ones.

const Member Functions

If you have a situation like this

const Mything the_unchanging_thing= Mything("Always this.");
the_unchanging_thing.dump();

The dump member function probably won’t compile because the compiler can’t be sure that the dump() function won’t mess with the calling object. And since this particular calling object, the_unchanging_thing, is constant, that would be wrong.

The way to handle this is to define the dump() function as a "const Member Function" (that’s the official way to refer to it). Add the const keyword to the end of the declaration and definition.

void dump() const;

friend

Sometimes you want to give access to other functions that are actually not part of your class. This is what friend functions can do. Use friend keyword in the declaration, not the definition.

Confusingly, you must put the friend function declaration in the class it doesn’t belong to prefixed with the friend keyword.

friend MyClass operator+(double x, const MyClass &mc);

This now can go in the MyClass declaration even though it’s not part of MyClass. It’s just a helpful random function that can now access MyClass as if it were a part of it. Note that this example helps for this order of arguments. If the order is reversed, the MyClass operator+ can just be overloaded the normal way. It seems common to use friend functions when overloading operator<<().

Classes can be friends too. By doing something like this.

class Body {
  public:
    friend class Clothes;
  ...

This type of arrangement will allow Clothes to access Body’s private parts.

virtual

The virtual keyword is confusingly used for different purposes depending on context. Here are two of the uses. There may be more.

  1. A function declared virtual means that an existing overriding function in a derived class is invoked.

  2. An inheritance relationship declared using keyword virtual between classes Derived1 and Derived2 that inherits from class Base means that another class Derived3 that inherits from Derived1 and Derived2 still results in the creation of only one instance of Base during instantiation of type Derived3.

See Abstract Base Classes for an explanation of "pure virtual functions".

Override

When a base class function is declared virtual its corresponding derived class functions should override it. It turns out that sometimes subtle errors can happen if the derived class has some defect in its correspondence to the base class. To make the errors less subtle and more obvious to the compiler such that sensible errors will be produced, C++11 offers the override declaration. Basic usage looks like this.

class Universal {
public:
    virtual void myfn();
};
class Specific: public Universal {
    void myfn() override; // Optional to begin with "virtual" here too.
};

One bizarre caveat on the override specifier is that it only is a keyword if it is in a proper place at the end of a member function declaration. This means that if you want a function called override() or a variable or whatever, you can do that. Obviously that’s going to be misleading these days to those in the know — but not to those really in the know. Obfuscated C++ writes itself! Gah!

A similar specifier is final which indicates that the function or class should not be overridden. It is in its final form.

Reference Qualifiers

Getting into crazy weird stuff is easy with C++ and my favorite example of "ok, you’ve gone too far" is reference qualifiers. I’m not going to pretend to understand the gory details but essentially you can specify if derived classes can override (not overload) base class functions depending on whether or not the member function is an lvalue or an rvalue.

Clearly that is ridiculous and the whole language should be scrapped if we need to regularly deal with ridiculous error bait like that. But I’m including it for completeness so that I can hopefully recognize this for what it is if I ever stumble across it in the wild. Here’s the syntax that should tip you off to this "feature".

Class Myclass {
public:
    void weirdfunction() &;  // Only when *this is an lvalue.
    void weirdfunction() &&; // Only when *this is an rvalue.
};
Myclass x;                   // Ordinary instantiation which is lvalue.

Note that if you ever use reference qualifiers you need to make sure all overloads use them otherwise the ambiguous ones may take precedence and screw things up.

I don’t even know when the function’s context would ever be rvalue (factory functions?) but that should be enough of a syntax hint to send you off in the right direction for proper research into the topic.

Abstract Base Classes

Taking some kind of obnoxious programming test? I had never heard of this and I suspect it has something to do with Java where abstract is a keyword; it is not in Cpp! But there are abstract base classes, sometimes referred to as ABC, in Cpp. An abstract base class is really just a class that contains one or more pure virtual functions. Class declarations containing at least one pure virtual function will not allow objects to be instantiated from that class.

A "pure virtual function" is one that ends with =0 like this.

void Move(int dx,dy) = 0;

That’s it. The =0 in the prototype means that the ABC doesn’t need to define the function. Also note the const member function version.

void Show(int dx,dy) const = 0; // But don't modify the calling object.

Member Initialization Lists

In class definitions the constructor can have a list of members with their correct initial values defined. These are placed after the constructor name and parameters, followed by a : and before the body of the constructor. The following are very similar. The first is preferred since it avoids unnecessary copies.

MyClass(int some_init_args):member1(5){}
MyClass(int some_init_args){member1=5}
Example of Member Initialization Lists
#include <iostream>
class Parent {
    public:
    Parent( int x ) {
        std::cout << "Parent's constructor"
        << " called with " << x << std::endl;
        }
    };

class Derived: public Parent {
    public:
    Derived() : Parent( 10 ) { // With "Member Initialization List".
        std::cout << "Derived's constructor" << std::endl;
        }
    };

class Strclass {
    public:
    Strclass() : thestr("This is the init string.") {
        std::cout << thestr << std::endl;
        }
    private:
    std::string thestr;
    };

int main() {
    Derived a_derived_instance;
    Strclass somesc;
    }

Exceptions

Recovering from errors in C is done by explicitly planning for every specific erroneous condition. In C++ there is a system of "exceptions" where (specifically) unanticipated errors can be treated reasonably.

While it is critical to understand exceptions I personally have some misgivings about them which are well documented in my Python notes. Without going into details here, I’ll sum up my personal opinion about C++ exceptions by quoting the Google C++ Style Guide which simply says, "We do not use C++ exceptions."

Here is a rough idea of how C++ exceptions work.

Example Of Exception Use
#include <iostream>
using namespace std;

void thefunction() { throw 99; }

int main (int argc, char *argv[]) {
    try {
        if (argc > 1){ thefunction();}
        else { throw '?';}   }
    catch(int e) {  // The catch is chosen based on its type.
        cout << "Exception number " << e << " has occurred." << endl;
    }
    catch (...) {  // If the type sent by throw is not defined, go here.
        cout << "Unknown exception has occurred." << endl;
    }
    return 0;
}

When this code is run with arguments it returns:

Exception number 99 has occurred.

When this code is run without arguments it returns:

Unknown exception has occurred.

Note that the catch statement is chosen based on the type specified by the throw command. In this simple example, this is not remarkable, but when defining your own types with classes, this mechanism can be very useful in organizing code to react to errors arising from different causes.

There are much fancier ways to use exceptions. You can define your own by inheriting standard exceptions. You can also catch and handle standard exceptions your own way. They can be nested such that the inner exception passes the information through to the outer ones.

Trying to document all weird syntax one might encounter, note that there exists a C++11 declaration specifier, i.e. a keyword, called noexcept. This is used to declare functions that are guaranteed not to ever emit exceptions. The point of this is that when the compiler must worry about exceptions, performance can be hit. This feature can allow the compiler to do the best thing. The syntax looks like this.

ReturnType myfunction(parameters) noexcept; // Most optimizable.
ReturnType myfunction2(parameters) throw(); // C&#43;&#43;98 style.
ReturnType myfunction3(parameters);         // Exceptions ahoy!

That throw() syntax is valid but not exactly the same as the noexcept syntax. Gah! Best to just leave the whole topic alone unless you step in a pile of it in someone else’s code, or it otherwise causes trouble.

Templates

Functions
template <typename T>
T functionName (T  parameter1,T  parameter2,...) { /* Function template. */ }

template <typename T1, typename T2>
T2 functionName (T1  parameter1,T2  parameter2,...) { /* Multiple types. */ }
Classes
template <class T>
class Number
{ private: T value; };

IntArray::IntArray(){ /* Normal constructor. */ }

template<class Type>
Array<Type>::Array(){ /* With template. */ }

Debugging

Since C++ is famous for having millions of lines of error output it’s good to intercept this where possible. The static_assert command will print a message if a condition is met at compile time.

For example, this checks to see if negative integers round down when divided.

static_assert(-3/2==-1)
static_assert(-3/2==-1, "Negative division rounds towards positive.")

The normal assert is for ensuring things are in order for run time and works the same way.

Standard Template Library

The near universal detest for STL in game development makes each studio’s code a silo of private libraries, which is unfortunate.

You don’t use STL where you need max performance, but performance isn’t the top priority for most code, even in games.

I don’t like STL much and rarely use it, but I do really like standards. The library situation with C++ is really a shame.

#ID_AA_Carmack (2014-04-05)
— John Carmack

Both C and C++ are very spartan languages and in order to do anything useful in either you pretty much need to write some tools to manage simple flexible data structures. This has been thought out in C++ with the Standard Template Library or STL.

Note that in modern times the STL is actually a subset of the C++ standard library that was inspired by an ancient template library that got integrated. Another way to say "STL" is roughly something like "containers/iterators of the standard library".

STL mostly provides templates that allow programs to easily create simple but powerful data structures for all kinds of pragmatic uses. This is the kind of stuff that higher level languages like Javascript and Python take for granted.

Containers
Container Adaptors
  • priority_queue

  • queue

  • stack

iterators

Iterators are pretty important in normal C++ and are pretty much how you rummage through STL containers of data. And lots of other things. You can have an iterator type that looks like this.

typedef std::vector<int>::iterator MyIterType;

One interesting thing that seems bonkers to me is that you can have, and should prefer, constant iterators. It seems to me that if an iterator’s whole point is going from one thing to another, that’s fundamentally not very constant. Here’s an example.

typedef std::vector<int>::const_iterator MyConstIterType;

My limited understanding (here’s more) is that the const_iterator type points to different stuff, it’s just that the stuff is immutable. Still look out for it and, in theory, if you can use it, the const gods will smile upon you.

Vector

A vector container is essentially a dynamic array. It has most of the advantageous properties of regular C arrays, mostly contiguous memory that can be accessed with predictable strides. Unlike regular C arrays, a vector can be dynamically resized as needs grow. This implies that vectors hog more memory than you may actually need them to, just in case you eventually want to use more than you thought you would. This also implies that once you use more than even this amount of memory, that an abrupt allocation of yet more memory may perhaps be needed along with a physical reshuffling of the contents; I don’t know if this can inject weird choppy performance issues, but it’s something to think about. The strategies used by vector to allocate additional memory are implementation dependent but seem to try to keep log(size) performance (adding twice as much a you had before when you run out).

The following sample program shows the basic STL container usage with a "vector" template.

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> V1; // Define a vector of integers.
    V1.push_back(9); V1.push_back(6); V1.push_back(3); // Load vector.
    for (int i= 0; i<V1.size(); i++) { cout << V1[i] << endl; } // Display values.
    vector<int>::size_type v_st= V1.max_size(); // Note namespace to use size_type.
    cout << "Max number of elements in a Vector<int>: " << v_st << endl;
}

Methods for vector include:

  • empty - Tests if container is doing any containing.

  • push_back - In software engineering English "append". Relatively quick. Cpp11 emplace_back follows the plan of emplace.

  • pop_back - Remove item from end. Relatively quick.

  • insert - Arbitrary insertion. Maybe slow unless near the end and reallocation can be minimized. There is also Cpp11 emplace which allows construction and insertion.

  • erase - Arbitrary removal (not just clearing, item size() is decreased). Also maybe slow unless near the end. I’m not sure if memory is reallocated down ever with this method, but it could be.

  • size - How many elements defined and present.

  • capacity - How many elements have been automagically provisioned for before the next reallocation would be required.

  • resize - Tries to set the number of items to that specified. If there were more items, they get harshly jettisoned.

  • reserve - Like a faux gearshift lever for an automatic transmission, you can ask to manually meddle in the automatic memory allocation. Or how about Cpp11’s shrink_to_fit which may do what’s on the tin (including remapping the whole thing) or, interestingly, it may do nothing.

Deque

The double-ended queue is similar to a vector in that elements can be accessed with random access indexing. The major difference is that items can be inserted at the beginning of the array while vectors allow only the end to expand. As a consequence of this feature another difference is that the deque is not guaranteed to live in contiguous memory. This means that offset pointers can’t be used, as with vectors, to access other items; if you try it will produce random nonsense behavior. The deque uses complicated chunks of memory that it grows as needed where needed. By splitting the container internals, better edits may be possible from the middle of the object and excellent edits are expected at either end. This kind of structure might be ideal for a FIFO queue.

Methods for deque include:

  • push_back, push_front - Add an item to the end or beginning.

  • emplace_back, emplace_front - Compose and add item to end or beginning.

  • pop_back, pop_front - Remove an item from the end or beginning.

  • insert - Add item to arbitrary location.

  • emplace - Compose and add item to arbitrary location.

  • erase - Remove item from arbitrary location.

  • clear - Remove all items from container.

  • swap - Exchange contents of two deque objects.

  • size - Returns number of items.

  • empty - Check if container is containing.

  • resize - Set the container to a limited specified number of items, losing any surplus.

  • shrink_to_fit - Asks the container to try and refactor to minimize memory usage so that it is just sufficient to contain the current items. Note that this is mostly a courtesy and not guaranteed to do anything.

List

An STL list is a doubly-linked list. It’s quick to insert one or many anywhere, but slow to find particular items deep in the chain. This means that inserting can be slow if you need to find the insertion point first. However it also implies that editing the ends of the chain is going to be quick.

Methods for list include:

  • size - How many elements (not storage/bytes). max_size for architectural top end.

  • assign - Fill in a particular value for the whole list or just a range, three6s.assign(3,6). Can be used to do a deep copy with something like mytargetlist.assign(mysrclist.begin(),mysrclist.end()); Playing with the iterators there seems to be the way to get slice functionality.

  • insert - Add existing element. emplace to construct and add (all emplace functions are Cpp11) .

  • push_front,push_back - Replace push with emplace to construct and insert.

  • pop_front,pop_back

  • erase, clear - Removes an element or range. Or remove all content. Use empty to check if empty.

  • remove and remove_if - Removes elements that match specific values or other conditions.

  • unique - Remove duplicates.

  • reverse - Change the order of elements.

  • sort - Unadorned, uses <. Can use custom comparison function. Note the difference between this template method and the generic STL sort which requires a random access container. Stick with the built in list sort method for lists.

  • merge - Combine ordered lists into another ordered list.

  • splice - Move elements between lists.

Here is an example of using a linked list. One helpful feature is that you can insert into the beginning of the list without actually remapping everything else. This is a rough implementation of the Unix tac command which reverses lines of input. The reversing is done simply by inserting each line read into the list of lines instead of appending each.

#include <iostream>
#include <fstream>
#include <list>
using namespace std;

void readit(istream& ins,list<string>& lines){
    string line;
    while (getline(ins,line)){lines.push_front(line);}
}

int main(int argc,char** argv){
    list<string> lines;
    if (argc>1){ // A file name argument should be present.
        ifstream ifile(argv[1]);
        if (ifile.is_open()) { // Double check that it opened ok.
            readit(ifile,lines);
            ifile.close();
        }
        else // Can't open the file for some reason.
            cout<<"Error: Unable to open file for reading!!"<<endl;
    } else { // No arguments? Use standard input then.
        readit(cin,lines);
    }
    for (list<string>::iterator i=lines.begin();i!=lines.end();i++)
        cout<<*i<<endl;
    return 0;
}

Note also this program roughly shows how to handle reading standard input or a file specified. Also note that the reverse method could have been used, perhaps with slightly more clarity of purpose.

Other Lists

I have notes about a singly-linked slist but this appears to be nonstandard. And it looks like Cpp11 has forward_list for that purpose.

Map

A very simple demonstration of the most basic map syntax.

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main () {
    map<string,int> piechart;
    piechart["C++"]=38;
    piechart["C"]=43;
    piechart["Python"]=19;
    cout << "C++'s value: " << piechart["C++"] << endl;
    cout << "C's value: " << piechart["C"] << endl;
    cout << "Python's value: " << piechart["Python"] << endl;
}

Reserved Keywords

asm, auto, bool, break, case, catch, char, class, const, const_cast,
const_iterators, continue, default, delete, do, double, dynamic_cast,
else, enum, explicit, export, extern, false, float, for, friend, goto,
if, inline, int, long, mutable, namespace, new, operator, private,
protected, public, register, reinterpret_cast, return, short, signed,
sizeof, static, static_cast, struct, switch, template, this, throw,
true, try, typedef, typeid, typename, union, unsigned, using, virtual,
void, volatile, wchar_t, while

cmath

Fancier math. Trig, logs, exp, sqrt, ceil, floor, abs. And wacky stuff like isnan.

#include <cmath>
M_PI // Is pi.
std::pow(base,exponent) // Exponents.
NAN // Is constant.

Set

A set is a container whose elements are always ordered (not sorted) and unique. Sets can be handy when trying to count unique items, even mildly complex ones as shown here with pair containers.

#include <iostream>
#include <utility>
#include <set>
using namespace std;
int main(void) {
    set<pair<int,int>> s;
    pair<int,int> p; // Not strictly necessary here.
    cout << s.size() << endl;    // Outputs: 0
    p.first= 0; p.second= 0; s.insert(p); // 1
    p.first= 1; p.second= 2; s.insert(p); // 2
    p.first= 3; p.second= 4; s.insert(p); // 3
    // Showing different way to compose set.
    s.insert(make_pair(5,6));             // 4
    s.insert(make_pair(1,2));    // Redundant, ignore.
    s.insert(make_pair(3,4));    // Redundant, ignore.
    cout << s.size() << endl;    // Outputs: 4
    return 0;
}
  • clear - Remove all elements from object.

  • insert - Put an item into the container. There is no sense of front or back since the item itself defines its place in the structure.

  • emplace - Composes and inserts an item. Also note emplace_hint which is similar but also takes a likely neighbor (one higher) and if that neighborhood is actually correct, the insert can be a lot quicker.

  • erase - Removes an item. This can be specified with the position index or by value which, in a set are pretty much the same thing.

Unordered Set

An unordered_set does not maintain an order. These can be quicker than regular sets. This is a Cpp11 thing.

Multiset

Allows duplicates.

  • find - Allows you to find the one or many items that match what you’re looking for.

Unordered Multiset

If you don’t want a strict ordering and you want duplicates to be valid, the unordered_multiset is a Cpp11 thing. For simplicity, imagine a Python dict where the keys are combined with an invisible nonce and there are no values; something like that.

Time

auto now= std::chrono::system_clock::now();

Random

Newish C++ has a civilized library for random number generation. To use this fine library, I needed to compile with -std=gnu++11.

#include <random>
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(0,255);
int rand_red_value= distribution(generator);

This library seems pretty comprehensive. It features different PRNG engines and a bunch of distributions. See the official documentation for details.

Another way I’ve seen is something like this.

#include <time.h>
#include <cstdlib>
int main() {
srand(time(NULL));
int target= rand()%100; // 0-99
std::cout << target << std::endl;
return 0;}

Eigen Library Matrix Operations

Examples of working with Eigen matrices
VectorXd my_vector(2);     // Vertical vector of two elements.
my_vector << 10, 20;       // Comma initializer sets coefficients.
cout << my_vector << endl; // cout prints the vector

MatrixXd my_matrix(2,2);   // Initialize Matrix with 2x2 dimensions.
my_matrix << 1, 2,
             3, 4;         // Set matrix to contain [[1,2],[3,4]].
cout << my_matrix << endl; // cout prints a matrix

my_matrix(1,0) = 11;       // Access by position. 2nd row, 1st column.
my_matrix(1,1) = 12;       // 2nd row, 2nd column
my_matrix.row(i) = my_matrix2.col(i); // Get/set row/col vector.

MatrixXd x
x.setZero(rows, cols);     // Fill with zeros. Also a `setOnes()`.
x.setConstant(rows, cols, value); // Fill with value.
x.setRandom(rows, cols);   // Random values.

MatrixXd my_matrix_t = my_matrix.transpose(); // Transpose.
MatrixXd my_matrix_i = my_matrix.inverse();   // Inverse.
MatrixXd my_mtimesv= my_matrix * my_vector;   // Matrix multiplication.

Here’s a nice polynomial fitting routine which uses Eigen.

double polyeval(Eigen::VectorXd coeffs, double x) {
  double result = 0.0;
  for (int i = 0; i < coeffs.size(); i++) {result += coeffs[i]*pow(x, i);}
  return result;
}

Eigen::VectorXd polyfit(Eigen::VectorXd xvals, Eigen::VectorXd yvals, int order) {
  assert(xvals.size() == yvals.size());
  assert(order >= 1 && order <= xvals.size() - 1);
  Eigen::MatrixXd A(xvals.size(), order + 1);
  for (int i = 0; i < xvals.size(); i++) {
    A(i, 0) = 1.0;
  }
  for (int j = 0; j < xvals.size(); j++) {
    for (int i = 0; i < order; i++) {
      A(j, i + 1) = A(j, i) * xvals(j);
    }
  }
  auto Q = A.householderQr();
  auto result = Q.solve(yvals);
  return result;
}

Eigen::VectorXd xvals(6);
Eigen::VectorXd yvals(6);
xvals << 9.261977, -2.06803, -19.6663, -36.868, -51.6263, -66.3482;
yvals << 5.17,     -2.25,    -15.306,  -29.46,  -42.85,   -57.6116;
auto coeffs= polyfit(xvals,yvals,3);
std::cout<< "Y(16)=" << polyeval(coeffs,16) << endl;

This excellent resource explains a low impact way to do "Cubic Spline interpolation in C++ ".

Makefile

Here’s a very simple Makefile that can be used on very simple C++ programming tasks.

ALLSRCS:= $(wildcard *.cc)
ALLEXEC:= $(ALLSRCS:.cc=)
.PHONY:all clean
all: $(ALLEXEC)
%: %.cc
    g++ -o $@ $<
clean:
    rm $(ALLEXEC)

Profiling

Wondering what the heck is taking so long in your program? You can get hints about what your program spends its time doing.

Do this
    sudo apt-get install linux-tools
    sudo bash -c "echo 0 > /proc/sys/kernel/kptr_restrict"
    perf record ./yourprog --your-opts
    perf report
Get a nice report like this
 18.28%  yourprog  yourprog       [.] Plist::querypoint()                    ▒
 13.85%  yourprog  yourprog       [.] shallowanglecull(Llist*, Tlist*, float,▒
  8.70%  yourprog  yourprog       [.] Llist::querypointA()                   ◆
  7.00%  yourprog  yourprog       [.] Llist::querypointB()                   ▒
  6.73%  yourprog  yourprog       [.] Vector::compareto(Vector)              ▒
  5.76%  yourprog  yourprog       [.] searchlinelist(Plist*, Plist*, Llist*) ▒
  5.69%  yourprog  yourprog       [.] operator==(Vector, Vector)             ▒
  5.55%  yourprog  yourprog       [.] Vector::~Vector()                      ▒
  3.92%  yourprog  yourprog       [.] Tlist::BBinterfere(Llist*)             ▒
  3.59%  yourprog  yourprog       [.] searchtrilist(Plist*, Plist*, Plist*, T▒
  2.96%  yourprog  yourprog       [.] Tlist::querylink()                     ▒
  2.88%  yourprog  yourprog       [.] Llist::queryA()                        ▒
  2.26%  yourprog  yourprog       [.] BBinthelper(float, float, float, float,▒
  1.89%  yourprog  yourprog       [.] Vector::gg_valX()                      ▒
  1.25%  yourprog  yourprog       [.] Llist::querylink()                     ▒
  0.92%  yourprog  yourprog       [.] Tlist::querypointC()                   ▒
  0.91%  yourprog  yourprog       [.] find_matching_pnum(unsigned int, Plist*▒
  0.90%  yourprog  yourprog       [.] Vector::Vector()                       ▒
                ...

Or if that isn’t good enough check out gprof.

Actually this hack is quite clever too. See the other suggestions there too (e.g. Valgrind).

Resources For Optimizing