No worries. For the longest time it never occurred to me they were different. I only began paying attention to it when I started doing template programming. For example,
1 2 3 4 5 6 7
|
template< typename T >
class Foo {
public:
Foo() {}
private:
T data;
};
|
default constructs data which, for non-POD types means it runs the type's default constructor, which should initialize data to some reasonable value. But as soon as
Foo is used with a POD-type (such as int), data is undefined because int's default constructor does nothing. Which is annoying if you're providing a template class like this whose default constructor wants to guarantee some kind of initial state to the user.
To fix this, you do:
1 2 3 4 5 6 7 8 9
|
template< typename T >
class Foo {
public:
Foo() :
data() // <---- note the parens!
{}
private:
T data;
};
|
when T = int, this means that data is assigned the value zero in this context.
(And this works for all other POD types, too -- char, float, double, etc.)
The problem with this syntax is that you can only do it in initializer lists because, for example:
forward declares a function named x that returns an int and takes no parameters, rather than declaring a variable of type int named x defaulted to 0.
This ambiguity in the grammar is what prompted the value_initialized template class in the boost library (
http://www.boost.org).