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.
Tuesday, November 30, 2010
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
int i=0; ++i=2;
The prefix increment returns an lvalue.
Postfix Increment
The following statements do not compile:
int i=0; i++=2
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.
int func() { if (0) return; }
This is a source of some nasty latent errors.
Time Complexity
The complexity of
int f(vectoris O(n).v) { int sum = 0; for (int i = 0; i < v.size(); ++i) { sum+=v[i]; } return sum; }
Time Complexity
The complexity of:
int f(vectoris O(n**2).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; }
Time Complexity
The complexity of int f(vector v) {return v.size();} is O(1).
Time Complexity
The complexity of
Note: O(1/2 n) is the same as O(n).
int f(vectoris O(n).v) { int sum = 0; for (int i = 0; i < v.size()/2; ++i) { sum+=v[i]; }return sum; }
Note: O(1/2 n) is the same as O(n).
Time Complexity
The complexity of
is O(log n).
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.
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.
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.
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:
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.
#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
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).
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.
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
type specifiers
function specifiers
Storage Class Specifiers
The following are C++ storage class specifiers:
auto
register
extern
static
mutable
auto
register
extern
static
mutable
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
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
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
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
::
:?
.
.*
sizeof
::
:?
.
.*
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.
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.
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
C89
C90
C++98
C99
C++03
Reference: http://www.suodenjoki.dk/us/archive/2007/cpp-standard-history.htm
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.
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.
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.
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:
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;
Example: typedef template
{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
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
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:
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
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.
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.
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:
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.
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).
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.
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
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:
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
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
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.
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:
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
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
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
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
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
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.
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
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
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
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
*
*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
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
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
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
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;
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.
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.
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:
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:
The above program prints out the following:
#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:
But the following does not compile:
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.
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:
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.
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:
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
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.
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
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
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
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.
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:
The second one is called a function try/catch block. Here is an example in a constructor:
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
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
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
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
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
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.
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
'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
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:
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.
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:
For the indexes inside a struct, the index needs to be declared as static for the statement to compile. Here is an example:
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.
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
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
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:
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
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
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
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.
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.
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.
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.
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.
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.
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.
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
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
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
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.
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.
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.
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.
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.
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)
Reference:
http://en.wikipedia.org/wiki/Aliasing_(computing)
Saturday, November 20, 2010
Dependent Names
Given the following:
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
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
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))();
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
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:
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.
#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.
Subscribe to:
Posts (Atom)