Tuesday, November 30, 2010

Mixin

mixin - A class not really designed for being an object, but for adding functionality to other classes.

Sometimes you see a NoCopy mixin, that prevents objects from being copied.

STL Functor

STL functor - Objects that override operator().

STL Trait

STL trait - A small policy object used to describe aspects of a type.

Traits are usually collections of typedefs that map template parameter to standard typedef names, for example, value_type.

STL Binder

STL binder - A function taking a function and a value and returning a function object.

STL Adapter

STL adapter - A function taking arguments and producing a function object.

Lvalues

lvalue - An expression referring to an object.

Incomplete Type

incomplete type - A type that allows an object to be copied, but not otherwise used.

Linkage

linkage - Whether a name is visible only inside or also outside its translation unit.

Reference

reference - Another name for an object.

Handle

handle - An object that controls access to another.

Design Pattern

Design Pattern - Reusable design, which describes a context, problem in that context, solution to problem, consequences for using solution. It also provides hints and examples.

Return Value Optimization

return value optimization - Avoidance of creation and destruction of temporaries when a function returns an object by value.

Diamond Inheritance

diamond inheritance - A class is derived from two difference base classes, which in turn are derived from the same base class. The inheritance diagram forms a diamond.

Integral Promotion

integral promotion - When a bool, char short, enumerator, bit field is converted to an int.

Double Dispatch

double dispatch - Selecting a functon based on dynamic type of two operands, aka multi-method.

Partial Specialization

partial specialization - A template used for the subset of template parameters that matches a specialization pattern.

Upcast

upcast - Casting from derived type to base type.

Downcast

downcast - Casting from base type to derived type.

Static Type

static type - The type given by a declaration.

Dynamic Type

dynamic type - The type given by an assignment.

Incrementing a bool Variable

You can increment (++) a bool variable.

If the variable is false, it will become true.
If the variable is true , it will stay true.

Decrementing a bool Variable

You cannot decrement (--) a bool variable, but you can subtract 1 from the variable.

Infinite Loop

The following is an infinite loop:

for (unsigned int i = 10; i < 0 ;--i) { printf("%d",i); }

The test part can never be false, because i can never become negative. This problem occurs more often, when the declation of i is farther from the loop.

Default Arguments

A static variable be used as a default argument.

You can even change the default argument's value during runtime, which can change the behavior of a function that is called without all of it's arguments. I don't know if there are any practical uses for this.

Initialization

Five elements are initialized to zero here: {int x[5] = {0};}

The first one is set because you specified the {0} initializer. The other four are set to zero, just because you specified an initializer. If you did not specify an initializer, the array would have random values in it.

Initialization

Only one element is initialized to 7 here: {int y[5] = {7};}

The first is set to seven, the rest are set to zero.

Postfix Increment

const MyClass operator++(int); is a postfix increment operator prototype.

MyClass& operator++(void); is a prefix increment operator prototype.

This can be remembered by the fact that the postfix increment needs to return a temporary value, and not an lvalue to the original object. So, the function return const is the postfix.

Note: postfix, infix, and prefix refer to the location of operator with respect to the operand.

Prefix Increment

The following statements compile:
    int i=0; ++i=2;

The prefix increment returns an lvalue.

Postfix Increment

The following statements do not compile:
    int i=0; i++=2

Return Statements

The value returned by the following function is undefined:

int func() { if (0) return; }

This is a source of some nasty latent errors.

Time Complexity

The complexity of

int f(vector v)
{
   int sum = 0;
   for (int i = 0; i < v.size(); ++i)
   {
      sum+=v[i];
   }
   return sum;
}
is O(n).

Time Complexity

The complexity of:

int f(vector v)
{
   int sum = 0;
   for (int i = 0; i < v.size(); ++i)
   {
      for (int j=0; j < v.size(); ++j)
      {
         sum+=v[i];
      }
   }
   return sum;
}
is O(n**2).

Time Complexity

The complexity of int f(vector v) {return v.size();} is O(1).

Time Complexity

The complexity of

int f(vector v)
{
   int sum = 0;
   for (int i = 0; i < v.size()/2; ++i)
   {
      sum+=v[i];
   }return sum;
}
is O(n).

Note: O(1/2 n) is the same as O(n).

Time Complexity

The complexity of

int f(vector<int> v)
{
   int sum = 0;
   for (int i = 0; i < log(v.size()); ++i)
   {
      sum+=v[i];
   }
   return sum;
}

is O(log n).

Time Complexity

The complexity of 3-SAT Problem is O(2**n).

1. The 3-SAT Problem is a variation of the Satisfiability problem. In the Satisfiability problem, you are given logic expression with N boolean variables, and asked if there is an assignment to these variables that will make the expression return true. The 3-SAT problem restricts the logic expression to or'd clauses of three variables.

2. The Satisfiability is the first algorithm that was proved to be NP-Complete. This is Cook's Theorem.

Reference: Computers and Intractability by M. R. Garey, D. S. Johnson. W. H. Freeman, 1979.

Time Complexity

The complexity of vector<int> quicksort(vector<int> v); is O(nlogn).

Time Complexity

The complexity of void f(vector<int> v) {} is O(1).

Time Complexity

An algorithm is PN-Complete if it can be transformed in polynomial-time to the 3-SAT problem.

Actually, it is PN-Complete if it can be transformed to an NP-Complete problem in polynomial time.

Reference: Computers and Intractability by M. R. Garey, D. S. Johnson. W. H. Freeman, 1979.

The long long Conversion String

The format conversion string "%lld" exists in ANSI C, but not in the C++ standard.

The size prefix "ll" was defined for ANSI C to correspond to the type 'long long', which has a size of at least 64-bits. Many C++ compilers allow "%lld" as a compiler with the corresponding type of 'long long int' as a compiler extension. The C++0x standard is expected to include 'lld" and the "long long" type.

Instantiation Order of Global Objects

The following program my crash:

#include <iostream>
using namespace std;

class MyClass
{
 public:
   MyClass()
   {
      cout << "Entering constructor\n";
   }
};

static MyClass myObject;

int main()
{
   return 0;
}


On SunOs 5.9, it crashes because the order of the instantiation of the global objects are not guaranteed. In this case the cout object is not created before the myObject object. If you add <stdio.h> and call printf() instead of cout, the program does not crash.

ANSI C Fuzzy Language Behavior

In the ANSI C standard, fuzzy language behavior is marked as one of the following, in order from least to most restrictive:
    undefined
   unspecified
   implementation-defined
   locale-specific

C Declarations and Definitions

In C, the difference between a declaration and a definition, is that the definition reserves storage.

In C, a definition is a declaration with a restriction (it reserves storage).

Declarations and Definitions

In C++, all declarations are definitions, while in C, all definitions are declarations.

In C++, a declaration is defined as a definition with restrictions.

The decl-specifiers

These are all or the C++ decl-specifiers:
    storage class specifiers
    type specifiers
    function specifiers

Storage Class Specifiers

The following are C++ storage class specifiers:
    auto
    register
    extern
    static
    mutable

Const

const a type specifier.

The decl-specifiers

The order of decl-specifiers does not matter to C++ compilers.

Monday, November 29, 2010

Template Points of Customization

The following are possible template points of customization:
    Member function
    Nonmember function + ADL (Argument-Dependent Lookup)
    Specialization
    Type lookup

Reference: www.ddj.com/cpp/184401876

Unnamed Namespace

An unnamed namespace can be defined in inside another namespace.

Natural Form of Operators

To use ADL (Argument-Dependent Lookup) on operators, operators must be used in their natural form, e.g. 'a+b' instead of 'a.operator+(b)'.

Partial Specialization

A class template can be partially specialized, but a function template cannot.

Explicit Qualification

ADL (Argument-Dependent Lookup) can be turned off by using explicit qualification.

Functions in Parentheses

ADL (Argument-Dependent Lookup) can be turned off by putting the function name in parentheses.

Reference: www.ddj.com/cpp/184401876

C++ Style Headers

All of the following headers have both the <x.h> and <cx> forms:
    assert.h
    ctype.h
    errno.h
    iso646.h
    float.h
    limits.h
    locale.h
    math.h
    setjmp.h
    signal.h
    stdarg.h
    stddef.h
    stdlib.h
    string.h
    time.h
    wchar.h
    wctype.h

Reference: www.ddj.com/cpp/184403367

Arrays of Functions

C and C++ do not allow arrays of functions. They allow arrays of function pointers.

Operators that cannot be Overloaded

The following operators cannot be overloaded:
    sizeof
    ::
    :?
    .
    .*

String

string is a typedef and not a class.

The virtual Base-specifier

The virtual base classes of the following class are C and E:

class A : B, virtual C, D, virtual E, F {};

The default base-specifier access-specifier is non-virtual.

Template Template Parameters

In the C++98 Standard, a template can take a template as a parameter.

template <template <typename> class T> class A {};

This was not implemented on several compilers. It does not compile on the studio8-v10/SUNWspro/bin/CC, but does compile on gcc.

C/C++ Standards

The following is a list of C/C++ standards in time order from earliest release to latest:
    C89
    C90
    C++98
    C99
    C++03

Reference: http://www.suodenjoki.dk/us/archive/2007/cpp-standard-history.htm

ANSI C

ANSI C is also known as C89.

The ISO ratification of ANSI C

The ISO ratification of ANSI C is also known as C90.

Kernighan and Ritchie (K&R) C

Kernighan and Ritchie (K&R) C was published in 1978.

C++'s Original Name

C++'s original name was C with Classes.

Reference: http://en.wikipedia.org/wiki/C%2B%2B

The First Commerial C++ Compiler

The first C++ compiler became comercially available in 1985.

Saturday, November 27, 2010

Base Class Access Specfiers

The private base classes of: class A : B, public C, D, private E, F {}; are B, D, E, and F.

The access specifiers: public, protected, and private are only associated with the immediately next class. This is different than when access specifiers are used with members, where an access modifier affects all members after it in a class, until another access modifier is seen by the compiler.

Public inheritance is usually associate with the ISA relationship, where as private inheritance is associated with the implemented-in-terms-of relationship. The use of protected inheritance is not as understandable, in terms of connecting it with a relationship, but protected inheritance allows the derived class to access all of the public and protected data of the base class. By members, I mean member functions and member data.

Template Bodies

If your template body is in a cpp file that does not instantiate the template, you will get a linker error if you try to instantiate the
template in another cpp file.


When the compler compiles the file (aka translation unit) that contains the template, it will only instantiate the types of the template that are in that file. These will be the only instantiations in the generated object file. This can seem mysterious, because the template might work for some types and not for others.

This is why it is recommended to put template bodies in the header that defines them.

Nested Templates

You can have nested templates.

Example:
template <class U, class V> class A {
public: template <class V> V function() {return V();} };

Note the the first 'class V' is unrelated to the second 'class V'. It is like having the second 'class V' being 'class W'. To fully instantiate the template, you to provide for class U, class V, and class V again. The following program shows a usage:

int main () {
   A<int,int> a;
   cout << a.function<float>(); 
   return 0;
}

The Writer of STL

The main writer of the STL was Alexander Stepanov. The writer of the Microsoft implementation of the STL was P. J. Plauger.

Templates in Typedefs

You use a template in a typedef.

Example: typedef template class Base_tag
{public: T data;} Base;

Typedefs

The following compiles: typedef struct Base_tag {int data;} Base;

Typedefs

The following compiles: typedef class Base_tag {int data;} Base;

Tags

The C++ grammer name of Base in: typedef class Base_tag {int data;} Base; is tag.

Tags

The C++ grammer name of Base in: class Base {public: int data;}; is tag, but it is also called class-name.

Enumerations

Given typedef enum Basic_tag {One = 1, Some = 2, Many = 10};Basic_tag is the enumeration and One is an enumerator.

Reference: http://www.glenmccl.com/glos.htm

Implicit Conversions

Converting a pointer to bool in an if statement is an example of implicit conversion.

It is an implicit conversion from pointer to bool. An integral promotion is when bool, char, short, enumerator or bit field is contverted to int. There is also integral conversion, where a signed int is converted to an unsigned int or vice versa.

Reference: http://www.glenmccl.com/glos.htm

Template Include is not Defined

When you get the following compiler error: "Template include is not defined", you are missing an '#' before an include directive.

Template Argument Deduction

All of the following template structures (plus more) that can be used in Template Argument Deduction:

    T
    const T
    volatile T
    T&
    T*

The full list is given in the reference below.

Reference: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/template_argument_deduction.htm

Include Paths

When using Windows, the paths in your #includes should use "/" and not "\", because it is guarenteed to work by the C++ standard.

Using "\" will only work in Windows. What sometimes happens when developing in Windows, is that developers use "\" in the include statements and also use mixed case for the header file names in the include statement. When it is decided to port to Linux or other Unix variant, there are a lot of compile errors.

The Pre-increment Operator

The following compiles: int i = 1;++++++i;

The preincrement operator returns an lvalue. Note that i++++++; does not compile, since the postincrement operator returns an rvalue. I would not

recommend coding like this.

Trick to Reducing the Copying of Large Vectors into Maps

When calling insert() on a map object. The value_type is copied once.

If you have a map from something to large vectors, to insert into that map, you would first call value_type(). This would cause
the large vector to be copied. When you call insert(), the large vector would be copied a second time.

Here is a technique to get rid of one of the large vector copies:

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

namespace {
   typedef vector<unsigned> MyVectorType;
   typedef map<unsigned, MyVectorType, less<unsigned> > U2VU;
   U2U  g_myU2U (less<unsigned>());
   U2VU g_myU2VU(less<unsigned>());
} // end unnamed namespace

int main()
{
   MyVectorType myVector;
   myVector.push_back(1);
   myVector.push_back(2);
   myVector.push_back(3);
   U2VU::value_type vt1(1,MyVectorType());
   U2VU::value_type vt2(2,MyVectorType());
   g_myU2VU.insert(vt1);
   pair<U2VU::iterator, bool> ret;
   ret = g_myU2VU.insert(vt2);
   if (ret.second == true) { // This means the key was not already there, 
                             // so the item was inserted.
      std::cout << "Inserting vector into map via iterator" << std::endl;
      ret.first->second = myVector;
   }
   std::cout << "U2VU has " << g_myU2VU.size() << " items in it." << std::endl;
   return 0;
}

The trick was to insert a value_type() with an empty vector, and then use the returned iterator to set the vector part to the large vector, thus saving a copy of the large vector.

Order of Function Parameters

The reason why some people recommend that the output parameters are listed first, and then input parameters in a call to a function is because default

input parameters must be on the right.

Although default parameters can also be used for output parameters (Steve Read).

Forward Class Declarations

A forward class declaration is not useful if the size of the class is needed, before the class was defined.

Reinterpret Cast

In C++, the reinterpret_cast<>() is used for implementation-dependent casts.

Translation Units

If five *.cpp files are included into one *.cpp file that is compiled; then there will be only one translations unit.
This is not recommended, though.

The Modulus Operator

In C, the value of (1 % (-2) ) is 1. Prior to C99 it could be 1 or -1, depending on the compiler.

Template Point of Declaration

The template's point of declaration is just before the word template.

When explicitly specializing a template, the decaration of the primary template must be in scope at "the point of declaration" of the explicit declaration.

Template parameters have the scope from their point of declaration to the end of it template; so, you can immediately follow a class T template parameter by a T *p template parameter.

References:
http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=/com.ibm.vacpp7a.doc/language/ref/clrc16name_binding.htm

http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/explicit_specialization.htm

http://www.kuzbass.ru/docs/isocpp/template.html

Template Point of Instantiation

Given:

template <T> 
int f(T a) {
    return sizeof(a);
} 

int main() {
   f<float>(4.0);
   return 0;
}

The template's point of instantiation is just before "int main".

A template declaration must be in scope at a template's point of instantiation.

Reference: http://publib.boulder.ibm.com/infocenter/compbgpl/v9v111/index.jsp?topic=/com.ibm.xlcpp9.bg.doc/language_ref/name_binding.htm

Function Specifiers

All of these are function specifiers: inline, virtual, explicit.

File Scope

The use of static for meaning file scope is deprecated in C++. The unnamed namespace should be used instead.

Reference: The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section:B.2.3

The char Type

Whether the char is signed or unsigned is implementation-defined.
Note that 'char', 'unsigned char', and 'signed char' are three different types.

Converting an Integer to Less Bits

When converting an integer into an unsigned integer with less bits, the MSBs are lost.

The following program demonstrates this:

#include <iostream>
using namespace std;
int main() {
   unsigned char c = 0xabcd;
   cout << "c: " << hex << static_cast<int>(c) << endl;
   return 0;
}

Unions

Any of the following disqualifies a class for being an element of a union: having a constructor, having a destructor, having a copy operation.

Otherwise the compiler would not know what constructor/destructor/copy operation to call.

Reference: The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section:C.8.3

Namespaces

When the goal is only to encapsulate names, namespaces are preferred over classes.

Reference: The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section:C.10.3

Inner Classes

Members of an inner class cannot access private members of an enclosing class.

Friends

If A is a friend of B and B is a friend of C, then A is not automatically a friend of C. I.e, the friend relationship is not transitive.

Friday, November 26, 2010

Disguised Pointer

A "disguised pointer" is a pointer stored as a non-pointer.
Although, this is not official C++ Standard terminalogy.

Reference: The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section: C.9.1.1

Using Directives

If a name in one namespace clashes with a name in another namespace, and both namespaces are in using-directives, it is not a compiler error if the name is not used.

This sometimes causes problems to suddenly appear, and motivates minimizing the scope of using statements. For example, it is not recommended having using statements in header files.

Reference: The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section: C.10.1

Friendship

Friendship is not inherited.

Reference: The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section: C.11.4

Assembly Code

C++ allows you to embed assembly code in the C++ code.
There is an 'asm' keyword that allows you to do this. Some platforms and compilers do not allow this though.

Declarations

The following are all parts of a declaration: specifier, base type, declarator, and initializer.

The format of a declaration is:
[specifier] <base type> <declarator> [initializer];

An example of a declaration with all of the parts is:
    const int i = 9;
Where
    'const' is a specifier
    'int' is the base type
    'i' is the declarator
    '= 9' is the initializer
Notes:
    1. The declarator is the name of the object, type or function
      that is introduced into a scope by the declaration.
    2. The following are examples of specifiers:
      {extern, static, mutable, auto, register} -- Storage Class Specifiers
    {virtual, inline, explicit} -- Function Specifiers
    {const, volatile} -- cv-qualifiers (also Type Specifiers)
    {struct, class, union, typename} -- Class Specifiers
    {long, long long, short, signed, unsigned} -- Type Specifiers
    {enum} -- enum Specifier
    {private, public, protected} -- Access Specifiers
    friend, inline, typedef
    template

References:
The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section: 4.9.1
http://www.kuzbass.ru/docs/isocpp/dcl.html

Declarations

The optional parts of a declaration are the specfier and the initializer. For example, the following is okay: int i;

Reference: The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section: 4.9.1

Declarations

Not all declarations are terminated by a semi-colon.
namespaces and function definitions don't use a semi-colon in the declaration.

Reference: The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section: 4.9.1

Declarator Operators

All of the following are declarator operators:
    *
    *const
    &
    []
    ()

Reference: The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section: 4.9.1

Declarator Operators

Postfix declarator operators have higher precedence than prefix declarator operators.

References:
The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section:4.9.1
http://www.velocityreviews.com/forums/t450319-declarator-operators.html

Using Declarations

When you use a using declaration, you create a local synonym.

References:
The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000. Section: 8.2.2
http://www.research.att.com/~bs/glossary.html

Thursday, November 25, 2010

Using Declarations versus Using Directives

A using-declaration is different than a using-directive.

A using-declaration brings one name into a scope. This name can be used as if it was declared locally.
For example,
    using std::vector;
Note that the keyword 'namespace' is not used.
A using-directive brings all the names of the namespace into a scope.
For example,
    using namespace std;
You can also have a namespace alias, which can be used make a namespace name shorter or clearer.
For example,

namespace WHAT_YOU_SEE_IS_WHAT_YOU_GET {
    void widget();
}
namespace WYSIWYG = WHAT_YOU_SEE_IS_WHAT_YOU_GET;

Reference: The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000, Section: 8.2.2-3

External Linkage

A name has external linkage if it can be used in a translation unit that is different that the one in which it was defined.

Destructors

You call a destructor explicitly, but you probably don't want to do it.

Reference: The C++ Programming Language by Bjarne Stroustrup. Addison-Wesley, 2000, Section: 10.4.1

The setw() Function

When writing to a stream, setting the width property only lasts to the write of the stream.

For example, if you want to put three 4's in a field width of 20, you would do this:
cout << setw(20) << 4 << setw(20) << 4 << setw(20) << endl;

IOS Flags

When writing to a stream, setting the justification property (e.g., right and left) continues until it is changed.

If you are writing a logger, it is programmatically polite to first save the ios flags with a statement like:
    ios::fmtflags flags = cout.flag(); // Save the flags.
    // Change cout flags the way you want.
    cout.flags(flags); // Restore the flags.

The difftime() Function

One of the reasons difftime() returns a double is because time_t can be either an integer or floating point type.
Otherwise, it would have been an int type.

The Default Allocator

The default allocator for type T is allocator<T>.

Template Parameters

Template parameters can refer to previous template parameters.

Here is an example:

template <class T, class CONTAINER = std::vector<T> > 
class MyContainer
{
 public:
   CONTAINER container;
};

operator void*()

The return value of the following prototype: operator void *(); has the type: 'void *

operator void *()

The following code compiles:

#include <iostream>
using namespace std;
struct MyStrm
{
  MyStrm()
  {
    d_cnt = 5;
  }
  operator void *()
  {
    return d_cnt ? &d_cnt : 0;
  }
  int get() {
    return d_cnt--;
  }
  int d_cnt;
};

int main()
{
  MyStrm myStrm;
  while (myStrm)
    cout << myStrm.get() << endl;
  return 0; 
}

The above program prints out the following:

5
4
3
2
1

Const

The folloiwng compiles:

      int                g_int        = 1;
const int               g_c_int       = 61;
const int       &       g_c_int_ref   = g_c_int;
      int const &       g_int_c_ref   = g_c_int;
      int       * const g_int_ptr_c   = &g_int;
      int const * const g_int_c_ptr_c = &g_int;
const int       * const g_c_int_ptr_c = &g_int;
      int const *       g_int_c_ptr_c = &g_int;

But the following does not compile:

const int const * const g_c_int_c_ptr_c = &g_int;

The const before or after the int specifies that the int cannot be change. The const after the '*' specifies that the pointer to the int cannot change. When you have three consts, you are specifying that the int is const twice, which is an error.

Try-Catch Block around MIL

A try-catch block can be wrapped around a constructor's member initialization list (MIL).

Here is an example of the syntax:

C::C()
   try
   :
   d_b(0)
   {
      // No exception
   } catch(...) {
      // Exception
   }

This is an example of the function try-catch block. I did not find it useful for constructors. It seems even if you catch the exception from d_b's constructor, your program is going to seg-fault using the Sun compiler and abort using the gnu compiler. The gnu compiler lets you do some work first in the catch block before it aborts you. With the gnu compiler on cywin, I was able to print out a message before being aborted.

Reference: http://www.cygwin.com
Cygwin has a free unix environment for Windows, that includes the gnu compiler, Perl and a lot of other utilities.

The ostringstream Member Function str()

The ostringstream member function str() converts an ostringstream to a string.

Here is a trivial example:

  std::string my_string;
  std::ostringstream my_ostringstream(
                      std::stringstream::in | 
                      std::stringstream::out );
  my_ostringstream << "Total: " << total;
  my_string = my_ostringstream.str();
  std::cout << my_string << std::endl;

Default Constructors for Elements in a Map

If you have a map to a class or struct, that class or struct needs a default constructor.

The default constructor is needed because of operator[]. When you try to access a map element that doesn't exist, operator[] creates the element with the element's default constructor

GNU Compilers

You should use the gcc compiler for C and the g++ compiler for C++.

Although gcc will compile C++ code, you will either need to 1) add switches; or 2) use g++ to link the C++ code.

Using the Gnu Math Library

If you want to use sin() in the gnu compiler for C, you have to use the -lm compiler option. You don't need it for the C++ compiler.

Note the library name will be libm.so, which is usually a symbolic link to a library name that includes the version such as libm.so.2

The wchar_t Type

In C++, you do not have to include a header file to use the wchar_t type. In C++, it is a primitive type. In C, you need to include wchar.h.

The strtoull() Function

The value of strtoull("15", 0 , 16) is 21.

strtoull() converts a string to an integer. In the case above, the string is interpreted as base 16. So 15 maps to (1*16) + 5*1 = 21. There are several strtoxxx()-like functions, here are some: atoi, atol, atoll, strtol, strtod

Reference: http://www.cplusplus.com/reference/clibrary/cstdlib/strtoul.html

Rethrowing Exceptions

When catching an exception e, is it better to rethrow the exception with 'throw;' rather than 'throw e;', because 'throw e' may throw away information if the exception was caught with a super class type. If the exception is caught by value, rethrowing the exception using the name of the exception will slice off any extra data, if the exception object is has a dynamic type more derived than the type in the catch specification. If the exception is caught by reference (using a reference (&) or pointer(*)), rethrowing the exception will not slice off the information. For the most part, it is better to re-throw without the variable name.

Reference: www.semantics.org

valarray

valarray does not have begin() and end() member functions.

The valarray is considered a "near-container" of the STL. There are three other "near-containers." They are:
    1) C-like array; 2) string; and 3) bitset
Reference: C++ How to Program (7th Edition) by H. M. Deitel, and P. J. Deitel. Prentice Hall, 1997, Section 20.11 Introduction to Containers.

Function Try-Catch Blocks

Both of the following function declarations compile:

void func1()
{
    try
    { }
    catch (...)
    {}
}

void func2()
try
{ }
catch (...)
{ }

The second one is called a function try/catch block. Here is an example in a constructor:

MyClass::MyClass()
try 
: d_mem1(0), d_mem2 
{ } 
catch (...) 
{ }

References:
Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library by Scott Meyers. Addison-Wesley, 2001.
C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003
http://www.gotw.ca

Exit Codes

EXIT_SUCCESS and EXIT_FAILURE are constants defined in the C++ language.

They are MACRO constants defined in cstdlib and stdlib.h

References:
Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library by Scott Meyers. Addison-Wesley, 2001.
C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003
http://www.gotw.ca

Remove() Algorithm

If you have a vector/list of 5 integers, whose values are all 8, and you call the remove function from the <algorithm> header file, and in that call you specify that you want all elements with the value of 8 removed. The value returned by the vector/list's size() member function will be 5.

References:
Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library by Scott Meyers. Addison-Wesley, 2001.
C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003
http://www.gotw.ca

Remove() Algorithm

If you have a list of 5 integers, whose values are all 8, and you call the remove function from the <list> header file, and in that call you specify that

you want all elements with the value of 8 removed. The value returned by the list's size() member function will be 0.

References:
Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library by Scott Meyers. Addison-Wesley, 2001.
C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003
http://www.gotw.ca

Declarations

The following compiles: int (i) = 1; The parentheses do not do anything here.

References:
Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library by Scott Meyers. Addison-Wesley, 2001.
C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003
http://www.gotw.ca

Default Constructors for Built-in Types

The following compiles: int i = int();

'int()' is "sort of" a default constructor for int which initializes 'i' to zero.

The following are other ways of initializing i to zero.

  int i = 0;
  int i(0);
  static int i; // Also changes the storage class.
  int i; // global, unnamed, or other namespace.

Built-in types do not have default constructors. They do have some syntax that initizializes a built-in typed variable to '0' converted to that type.
For example:
    float f = float();
The above is equivalent to float f = static_cast<float>(0);.

Sometimes, in templates, you will see declarations as follows: T element = T();
This is to catch the case when a built-in type is passed as the template argument for the template parameter T. If you left the "= T()" off, the default constructor would be called for all types except the built-in types.

References:
Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library by Scott Meyers. Addison-Wesley, 2001.
C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003
http://www.gotw.ca

Simple Statements

The following statement compiles: 5;

A popular typo is to forget the "()" on a function call. The compiler does not complain, but nothing happens instead of the function being called.

References:
Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library by Scott Meyers. Addison-Wesley, 2001.
C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003
http://www.gotw.ca

Wednesday, November 24, 2010

User-defined Return Types

The following compiles:

class X
{ };

X funcX() 
{
  X x;
  return x;
}


int main() {
  X x2;
  funcX() = x2;
  return 0;
}

x2 is assigned to the temporary returned by funcx().

If a built-in type, such as int was used instead of class X, the program would not compile. This is because for built-in return types, rvalues are returned. For user-defined return types, lvalues are returned. In the user-defined case, it is useless to assign to a returned temporary, and so this is is usually a runtime bug.

Tuesday, November 23, 2010

Namespaces

You cannot declare a namespace inside a class.

Namespaces

If Nx represents a namespace and Sx represents a struct or class, all of the following compile:

N1::N2::N3::index = 1;
N1::N2::S3::index = 1;
S1::S2::S3::index = 1;
N1::S1::S2::index = 1;


For the indexes inside a struct, the index needs to be declared as static for the statement to compile. Here is an example:

namespace N1 { namespace N2 {
  struct S3 {static int index;};
    int S3::index = 4;
}}

Pointers

The following compiles:

int main() {
  int i = 0;
  int *ip = &i;
  int **ipp = &ip;
  int ***ippp = &ipp;
  int ****ipppp = &ippp;
  ****ipppp = 4;
  return 0;
}

Union Templates

A union be a template; although, I have not seen this done in practice.

Nesting extern "C" Statements

You can nest 'extern "C" {' statements.

Nesting extern "C" Statements

You can nest 'extern "C" {' statements inside an 'extern "C++" {' statements.

Template Declarations

When declaring a template, you can use: tempate <class T> and template <typename T>, but not template <struct T>.

You can pass a struct as a template argument, but the template parameter needs to be declared with either 'class' or 'typename'. Using 'typename' is preferred, because 'class' can be confusing.

Taking an Address of an Lvalue

You can take the address of (&) an lvalue, but not an rvalue.

An lvalue refers to an object. An rvalue refers to the value in an object. lvalues can be implicitly converted to rvalues, but rvalues cannot be implicitly converted to lvalues.

Reference:
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/lvalue.htm

Type Decay

The following compiles:
int myArray[5] = {3};
const int (*s)[5] = &myArray;

'int myArray[5]' has a different type than 'int *myArray'. Sometimes the first type will be converted by the compiler to the second type. This conversion is sometimes called 'decay.' In this case 'decay' means loss of type information.

References:
C++ Templates by David Vandevoorde. Addison-Wesley, 2003.
http://cpptruths.blogspot.com/2005_06_01_archive.html

Const and Extern Specifiers

All of the following statements compile:

extern int const i1 = 42;
         int const i2 = 42;
  const  int       i3 = 42;
  const extern int i4 = 42;
  const extern int i4 = 42;


Some people such as authors David Vandevoorde and Nicolai M. Josuttis prefer the int const' versions of the above declarations.

References:
C++ Templates by David Vandevoorde. Addison-Wesley, 2003.
http://codecraft.pool-room.com/Cpp/const-correctness-3.html

Function Returning Lvalue

The following program compiles and prints:
1
2

#include <iostream>
using namespace std;

int & func() {
  static int temp = 1;
  cout << temp << endl;
  return temp;
}

int main() {
  func() = 2;
  func();
  return 0;
}

Monday, November 22, 2010

Zero Element Arrays

On some compilers the following compiles, on others, it does not: int myArray[0];
    In g++, yes.
    In Microsoft C++, yes.
    In Sun CC, no.
    In the C++ Standard: It used to be not allowed (ISO/IEC 14882:1998(E)). I am not sure if it was later permitted, or some compilers do it as an extension and/or bug.

For size tests, I used g++ to compile. A struct with just an empty array has size 0; so does an object of this struct. Interestingly, an empty struct has 1 byte, so that you are able get the address of a corresponding object. This is different than in C, where an empty struct is zero-bytes. Several zero-byte objects get the same address with g++.

A C++ struct with only non-virtual functions doesn't change the size, but if you add a virtual function, the size typically changes to accommodate a virtual function table pointer.

C++ Standard does allow int *myArray_p = new [0];

C (C90) and C++ allow dynamic arrays such as the following:
  int sizeofArray(int nbrOfElements)
  {
      int myArray[nbrOfElements];
      return sizeof(myArray);
  }
which allows 0 to be passed, and report a size of 0.

Zero-length arrays are not a big consideration for most people. I have only seen it considered with template design.

References:
   C++ Templates by David Vandevoorde and Nicolai M. Jouttis. Addison-Wesley, 2003.
   More Exceptional C++, by Herb Sutter. Addison-Wesley, 2002.
   http://www.ishiboo.com/~nirva/c++/C++STANDARD-ISOIEC14882-1998.pdf

Default Template Arguments

You can specify default template arguments in a class template.

Reference: C++ Templates: The Complete Guide by David Vandevoorde and Nicolai M. Jouttis. Addison-Wesley, 2003.

Default Template Arguments

You cannot specify default template arguments in a function template.

Reference: C++ Templates by David Vandevoorde and Nicolai M. Jouttis. Addison-Wesley, 2003.

Function Template Argument Deduction

In function template argument deduction, the return type of conversion operator members taken into account.

Reference: C++ Templates by David Vandevoorde and Nicolai M. Jouttis. Addison-Wesley, 2003.

Function Template Argument Deduction

In function template argument deduction, the return type of non-conversion operator members are not taken into account.

Reference: C++ Templates by David Vandevoorde and Nicolai M. Jouttis. Addison-Wesley, 2003.

Separation Model of Templates

Using the "export" keyword in a template declaration allows a compilation unit that uses a template to only see the declaration of the template without having to see the definition.

This is part of the Separation Model of Templates. Most people use the Inclusion Model, where the template declaration and definition are both in the header file.

Reference: C++ Templates by David Vandevoorde and Nicolai M. Jouttis. Addison-Wesley, 2003.

Template Ids

Given the following declaration: template <typename T> class Stack;
Stack<int> is a template id, and Stack is not a template id.

Reference: C++ Templates by David Vandevoorde and Nicolai M. Jouttis. Addison-Wesley, 2003.

Member Template Functions

Member template functions cannot be declared virtual.

Reference: C++ Templates by David Vandevoorde and Nicolai M. Jouttis. Addison-Wesley, 2003.

Templates and C Linkage

A template cannot be defined or declared inside an extern "C" block, i.e., it cannot have "C linkage".

Reference: C++ Templates by David Vandevoorde and Nicolai M. Jouttis. Addison-Wesley, 2003

Non-Type Parameter Declarations

The following specifiers can be included in a non-type template parameter declaration:
    const
    volatile

The following specifiers cannot be included in a non-type template parameter declaration:
    static
    mutable

Reference: C++ Templates by David Vandevoorde and Nicolai M. Jouttis. Addison-Wesley, 2003.

Const Volatile Member Functions

void cvFunc() const volatile {} is a valid member function definition.

Const and Volatile

A variable can be declared const and volatile at the same time.

Int Implicitly Converted to bool

In the statement: if (1) {} The '1' is implicitly converted to bool.

Also the value of (true == 1) is true.

Reference: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=176

Kinds of Pointers

There are three kinds of pointers: Owned, Smart/Shared, and Dumb/Interface.

The following are examples of each kind:
    Owned: Resource Allocation Is Initialization (RAII)
    Shared: Reference Counting
    Interface: Clients use and/or copy but never delete.

For the most part in C++, the delete statements should be in destructors. Also, as part of C++ design, it is important to decide the ownership of pointers. Although, you can get C++ code to work by peppering your code with flags and deletes, it is more maintainable to use the above perspective with pointers.

Reference: "C++ Design", Unpublished manuscript by Steve Weinrich.

Sunday, November 21, 2010

Anonymous Unions

Members of an anonymous union look like members of the enclosing class.

Without using anonymous unions in classes, you need to use the union name when referencing a union member. For example: myObject.myUnion.myMember instead of myObject.myMember.

Reference: C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003, p. 143.

Template Keyword

The following can be valid syntax:
    p->template MyClass<int>::f();
    p.template MyClass<int>::f();

I have only seen this used in book referenced below. Sometimes the template keyword is necessary, but only if the compiler has trouble figuring out that something is a template. If the compiler can figure it out, then it is an error to include the template keyword.

Reference: C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003, p. 131.

operator int&()

'operator int&()' is functionally equivalant to 'operator int bitand()'; although it is more useful for Obuscating C++ Contests.

Reference: C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003, p. 120.

Qualified Names

All of the following are qualified names:
    A::B
    a.b
    a->b
Many people use the term only for A::B.

Reference: C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003, p. 119.

Aliasing

It is illegal to convert int* to short*. Punishment includes possible, but not limited to, ignored assignments.

Reference:
    http://en.wikipedia.org/wiki/Aliasing_(computing)

Saturday, November 20, 2010

Dependent Names

Given the following:

template <typename T>
  class Bag
  {
    vector<T> d_bag;
   public: 
    int count();
    void add(T element);
    void remove(T element);
  };

The following are dependent names (wrt templates):
    a. vector<T>
    b. Bag
    c. Bag<T>
    d. this->d_bag

The following are not dependent names:
    x. count
    y. d_bag
    z. Bag<int>

'a' because the name "vecter<T>" depends on T. If T is int, then the name becomes vector<int>.
'b' because Bag's name also depends on T. If T is int, then the name becomes Bag<int>.
'c' for same reason as 'b'.
'd' because 'this' represents Bag which is a dependent name.

not 'c' because the name 'count' stays the same no matter what T is.
not 'd' for same reason as 'c'
not 'e' because the Bag<int> name no longer depends on T.

Reference: C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003, p. 121

Object Declaration

Given the following declaration:class Base1 {} Base2; Base2 is an object and not a class.

This is an object (or instance). By convention 'Base2' should have been named 'base2' with a lower first letter.

A name that has several words with all but the first word capitalized (first letter of the word uppercase) is called Camel notation, because of the pattern lowercase, uppercase, lowercase, .... A name that has all of the words Capitalized is called Pascal notation, because it was the convention for programming in the Pascal Language. Putting the type information in lower letters in front of a name is called Hungarian notation. It was invented by Charles Simonyi, an Hungarian- American who worked for Microsoft. An example of this notation is szName for an null-terminated string. Micosoft used to use this notation a lot, but now discourages it; they rather have you use their programming environment to provide you with the type information.

References:
http://en.wikipedia.org/wiki/Hungarian_notation

http://en.wikipedia.org/wiki/Charles_Simonyi

Function Referencing

Given the following function definition:
   int func() {return 6;}

The following compile:
   func();
   (&func)();
   (*(&func))();
   (&(*(&func)))();

The following do not compile:
   &func();
   (&(&func)())();
   *(&(&func))();

Anonymous Classes

The following is an example of an unnamed class:
   typedef struct {int x, int y} Pair;

For struct and class, the struct/class name is between the struct/class keywork and the opening '{'.

In C++ whenever the name of the thing is left off, the thing is said to be anonymous. Here are are some other things that can be anonymous: enums, unions, variables (e.g. return (1+2);), arrays, functions (aka functors).

Reference: C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003, p. 121

Friday, November 19, 2010

Metaprogramming

The following program:

#include <iostream>
template <int N> struct X {
  enum {result = 2 * X<N-1>::result};};
template <>  struct X<0> {
  enum {result = 1};};
int main() {
  std::cout << X<16>::result << std::endl;
  return 0;
} 

This is an example of metaprogramming with C++ templates. The code would be more clear if I changed the "X" to "Power". At the 1994 C++ Standardization Committee Erwin Unruh showed that compilers can do more complex calcuations. It was latter shown that C++ Template Metaprogramming is Turing Complete, meaning that it can compute anything that is computable. This is in theory. In practice, the C++ Standard recommends 17 levels of recursion. The above code uses 16. For a more detail on Template Metaprogramming see: http://en.wikipedia.org/wiki/Template_metaprogramming


Reference: C++ Templates by David Vandevoorde and Nicolai M. Josuttis. Addison-Wesley, 2003, p. 302.