- Overview
-
Table of Contents
- Special Member Functions: Constructors, Destructors, and the Assignment Operator
- Operator Overloading
- Memory Management
- Templates
- Namespaces
- Time and Date Library
- Streams
- Object-Oriented Programming and Design Principles
- The Standard Template Library (STL) and Generic Programming
- Exception Handling
- Runtime Type Information (RTTI)
- Signal Processing
- Creating Persistent Objects
- Bit Fields
- New Cast Operators
- Environment Variables
- Variadic Functions
- Pointers to Functions
- Function Objects
- Pointers to Members
- Lock Files
- Design Patterns
- Dynamic Linking
- Tips and Techniques
- Five Things You Need to Know About C++11 Unions
- A Tour of C99
- A Tour of C1X
-
C++0X: The New Face of Standard C++
- Reference Wrapper
- The Performance Technical Report
- auto for the People
- Ironing Templates' Syntactic Wrinkles
- Visual C++ Becomes ISO Compliant
- A Garbage Collector for C++
- C99 Core Features in C++0X
- The <code>shared_ptr</code> Class
- The shared_ptr Class, II
- Lambda Expressions and Closures, Part I
- Lambda Expressions and Closures, Part II
- Lambda Expressions and Closures, Part III
- The Type Traits Library, Part I
- The Type Traits Library, Part II
- The Type Traits Library, Part III
- finally Revisited
- The Any Library
- The nullptr Keyword Proposal
- Delegating Constructors
- The Explicit Conversion Operators Proposal
- Conditionally-Supported Behavior
- The weak ptr Class Template, Part I
- The weak ptr Class Template, Part II
- POD Types Revisited
- The rvalue Reference Proposal, Part I
- The rvalue Reference Proposal, Part II
- Proposal for New String Algorithms
- Concepts, Part I
- Concepts, Part II
- constexpr: Generalized Constant Expressions
- The <u>constexpr</u> Proposal: Constructors
- Strongly-Typed enum Types
- C++09: The Road Ahead
- C++09: Proposals by Statuses
- Changing Undefined Behavior to Diagnosable Errors
- New Character Types
- The __func__ Predeclared Identifier is Coming to C++
- Static Assertions
- The extern template Proposal
- Variadic Templates, Part I
- Variadic Templates, Part II
- Variadic Templates, Part III -- Critique
- Using unique_ptr, Part I
- Using unique_ptr, Part II
- Unrestricted Unions, Part I
- Unrestricted Unions, Part II
- Unrestricted Unions, Part III
- Types With No Linkage as Template Arguments
- New Initialization Syntax
- Initializer Lists and Sequence Constructors
- New Standard Library Algorithms
- Class Member Initializers
- Inheriting Constructors
- Introducing Attributes
- The Removal of Concepts From C++0x
- The Future of C++0x, Part I
- The Future of C++0X, Part II
- The Debate About Attributes, Part I
- The Debate About Attributes, Part II
- The Debate About Attributes, Part III
- The Debate About Attributes, Part IV
- Forward Declarations of Enum Types
- The SCARY Iterators Proposal, Part I
- The SCARY Iterators Proposal, Part II
- Heading for Deprecation: <tt>export</tt>, Exception Specification and <tt>register</tt>
- The Rejection of the Unified Function Syntax Proposal
- Rvalue References as Object Members
- FCD Approved
- The Debate on noexcept, Part I
- The Debate on noexcept, Part II
- The Debate on noexcept, Part III
- About-face -- [[Attributes]] to Be Replaced with Keywords
- Will Delegating Constructors Be Removed From C++0x?
- Rvalue References: Past, Present and Future, Part I
- Rvalue References: Past, Present and Future, Part II
- Rvalue References: Past, Present and Future, Part III
- A Move in the Right Direction, Part I
- A Move in the Right Direction, Part II
- New Keywords for Inheritance Control, Part I
- New Keywords for Inheritance Control, Part II
- FDIS Approved
- C++0x Concurrency
- The Reflecting Circle
- We Have Mail
- The Soapbox
- Numeric Types and Arithmetic
- Careers
- Locales and Internationalization
New Initialization Syntax
Last updated Jan 1, 2003.
C++03 has many different and confusing syntactic forms for initialization.
In addition, there is no way to initialize containers, POD member arrays, and
dynamically allocated POD arrays. The C++09 standard fixes these problems with a
new uniform initialization syntax.
C++03 Initializer Babel
C++03 distinguishes between two major categories of objects when initialization is concerned: aggregates and class objects. An aggregate uses braces for initialization:
int n[2]={0,1};
struct S //aggregate
{
int x,y;
};
S s={0,1};
Class objects with a user-defined constructor cannot use the brace notation. Instead, they use an initializer list enclosed in parentheses:
struct S1
{
explicit S(int i int j) : x(i),y(j){};
private:
int x, y;
};
S1 s(0,1); //parentheses required instead of braces
Alternatively, class objects with a user-defined constructor may use default initialization, copy-construction syntax or an assignment operator syntax for their initialization:
std::string s1; //default initialization
std::string s2=("hello"); //parentheses with an initializer
std::string s3(s2); //copy constructor initialization
std::string s4=s2;//copy constructor initialization that uses the = notation
Arrays
Arrays of class objects are even more perplexing. In most cases, they do not include an explicit initializer at all. Instead, each array element is default initialized:
std::string s[10]; //default initialization std::string *ps=new string[2];//default initialization
As opposed to a common belief, there is a way to use the non-default constructor in an array initialization. However, this form of initialization is inconvenient and cannot be used with dynamically allocated arrays:
std::string s[2]= {string("ab"), string("cd")};
std::string s2[2]= {("ab"), ("cd")}; //same as above but shorter
std::string *ps=new string[2]={"ab", "cd"};//compilation error
Classes that have arrays of POD types as data members are another known problem. There is no way to initialize array members at all:
class C
{
int n[5];
double *pd;
public:
C(): n(0,1,2,3,4) {}//compilation error
explicit C(int i, int j, int k, int l, int m): {n={i,j,k,l,m}; }//also a compilation error
explicit C(int sz): pd(new double[sz]) {} //how to initialize the array pd?
};
You can look for creative syntactic notations but that won't do -- in C++03 there simply is no way to initialize the member array n nor is there a way to initialize the elements of pd. Instead, programmers tend to assign, rather than initialize, these members manually:
explicit C::C(int sz): pd(new double[sz])
{
for (int i=0; i<sz; i++)
{ //manual assignment used as "initialization"
pd[i]=0;
n[i]=i
}
}
Containers
Things get messier when you use containers. Suppose you have a vector of strings that you want to initialize. In C++03, you have to "initialize" such a container manually using a sequence of push_back() calls:
vector <string> vs;
vs.push_back("ab");
vs.push_back("cd");
vs.push_back("ef");
Conclusion: C++03 Initialization is Messy
The confusing rules regarding initialization are particularly problematic when it comes to templates. A template can't tell whether its argument t is a class object, an aggregate or a fundamental type unless you resort to type traits that often lead to obfuscated code and design compromises. In addition, C++ programmers find it hard to follow the seemingly arbitrary and inconsistent rules of initialization. The C++ standards committee agreed that these inconsistent initialization rules needed a thorough reform. At last, the C++09 Committee Draft introduces a new syntactic notation for initialization.
C++09 New Initialization Syntax
In June 2008 the C++ standards committee voted in a new proposal for a uniform initialization notation for class objects, arrays, aggregates, dynamically allocated arrays and even containers. Generally speaking, the new rules allow you to use braces more liberally. For example, you can initialize an object that has a user-defined constructor like this:
class C
{
int a;
int b;
public:
C(int i, int j);
};
// C++0x object initializer
C c ={0,0}; //C++09 only. Equivalent to: C c(0,0);
Of course, the traditional parenthesized initializer is still valid in C++09.
With respect to containers, you can say goodbye to a tedious list of push_back() calls. In C++09, you initialize standard containers intuitively with braces:
// C++09 container initializer
vector<string> vs={ "ab", "cd", "ef"};
map<string, string> rescue_team =
{ {"Tim Geithner", "+1 (212) 555-7890"},
{"Larry Summers", "+1 (212) 555-0987"}};
How does it work? Under the hood, all C++09 Standard Library container classes use a special constructor called a sequence constructor (I will discuss this topic in a separate column). Without getting into the technical details, these sequence constructors make the containers initializations above "just work".
Finally, we're getting to the onerous problems of member arrays and dynamically allocated arrays. C++09 allows you to use braces to initialize them intuitively and safely. Here's an example of a C++09 array member initialization:
class C
{
int n[5];
public:
C(): n{0,1,2,3,4} {}//C++09 only
};
Similarly, you can now initialize a dynamically-allocated array like this:
int* pi = new int[4] {1,2,3,4};//C++09 initialization
Compiler Support
Certain compilers (GCC 4.4 for example) already support the new initialization syntax. Other compilers will surely follow suit in their forthcoming releases.
