- 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
- A Tour of C99
- C++0X: The New Face of Standard C++
- Reference Wrapper
- The Performance Technical Report
- auto for the People
- Multi-Variable Declarations with auto
- Ironing Templates' Syntactic Wrinkles
- Visual C++ Becomes ISO Compliant
- A Garbage Collector for C++
- C99 Core Features in C++0X
- The
shared_ptr
Class - The shared_ptr Class, II
- Introducing the Lambda Library
- The Type Traits Library, Part I
- The Type Traits Library, Part II
- The Type Traits Library, Part III
- finally Revisited
- The Any Library
- The <limits> 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 constexpr Proposal: Constructors
- Strongly-Typed enum Types
- Explicit Virtual Overrides
- 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
- Thread Local Storage
- Defaulted and Deleted Functions, Part I
- Defaulted and Deleted Functions, Part II
- Extended Integer Types
- Garbage Collection: The Latest Proposal, Part I
- Garbage Collection: The Latest Proposal, Part II
- Garbage Collection: The Latest Proposal, Part III
- Extending sizeof to Apply to Non-Static Data Members without an Object
- The prohibited Access Type
- The Range Library
- Dynamic Initialization and Destruction with Concurrency, Part I
- Dynamic Initialization and Destruction with Concurrency, Part II
- The Reflecting Circle
- We Have Mail New
- The Soapbox
- Numeric Types and Arithmetic
- Careers New
- Locales and Internationalization
C++0X: The New Face of Standard C++
Last updated Aug 20, 2004.
The current C++ standard, officially known as ISO/IEC 14882, is already six years old. The C++ standards committee is currently working on extending and enhancing C++. Most of the work focuses on additions to the Standard Library, with very minimal core languages changes. In this series, I will explore some of the novel features added to the Standard Library.
Rationale
Extensions and enhancements are the best indicator that a programming language is being used heavily in the real world, rather than being confined to esoteric academic niches. Therefore, it's no surprise that the current standard undergoes an overhaul. There's no need to panic, though: C++ will still remain the same C++ as you've known for years, except that it will include many new facilities that are long overdue.
The standardization process is long winded but it will pay off in the long run. When you consider the frequent wholesale upheavals that new programming language undergo with every new release, I'm sure you'll agree that it's better to make a good standard right from the start (even if it takes longer), than to rush the standardization process only to discover later that "My goodness, we forgot generics!"
As I showed before, adding a half-baked feature at the last moment is never a good idea. The committee is well aware of this. Therefore, proposals for new features are always based on existing implementations. For instance, the regular expressions library of C++ (to which I will dedicate a separate column) is based on the boost::regex library. This way, the feedback of users can help the designers fine-tune their implementation, and add new features to it. Only then is the refined implementation proposed to the committee.
The official paper that specifies the newly added features is called The Standard Library Extensions Technical Report (known as the "Library TR"). The committee in turn reviews the TR, suggesting improvements, proper Standardese and implementation guidelines. There is no obligation to accept the facilities described in the TR as-is; in fact, it is more than likely that the final version will look different. Namespace issues, naming conventions, exception-safety, interaction with existing Standard Library components and other factors will affect the final version of the proposed features. Therefore, all the code listings, class and function names, and other design and implementation details provided in this section are subjected to change.
The <tuple> Library
The Library TR includes a new header file, <tuple>, that contains a tuple class template and its helper functions. A tuple is a fixed-size heterogeneous collection of objects. Several programming languages (e.g., Python and ML) have tuple types. Tuple types have many useful applications, such as packing multiple return values for a single function, simultaneous assignment and comparison of multiple objects, and grouping related objects (such as a function's arguments).
A tuple's size is the number of elements stored in it. The current specification supports tuples with 0-10 elements. Each element may be of a different type. The following example creates a tuple type that has two elements: double and void *:
#include <tuple> tuple <double, void *> t(2.5, &x);
If you omit the initializers, default initialization will take place instead:
tuple <double, std::string> t; //defulat initialized to (0.0, string())
Helper Functions
The make_tuple() function simplifies the construction of tuple types. It detects the types of its arguments and instantiates a tuple type accordingly:
void func(int i); make_tuple(func); // returns: tuple<void (*)(int)> make_tuple("test", 9); // tuple< const char (&)[5], int>
To examine a tuple's size, use the use the tuple_size() function:
int n=tuple_size < tuple <int, std::string> >::value;//2
To obtain the type of an individual element, use the tuple_element() function:
tuple_element() returns the type of an individual element. This function takes an index and the tuple type. The following example uses this function to retrieve the type of the first element in a tuple:
T=tuple_element <0, tuple<float, int, char> >::type;// float
To access the element itself, either for reading its value or assign a new value to it, use the get<>() function template. The template argument (the argument passed in the angular brackets) is the index of sought-after element, and the argument in parentheses contains the tuple type:
tuple <int, double> tpl; int n=get<0>(tpl); //read 1st element get<1>(t)=9.5; //assign to the 2nd element
Applications
Functions with a dual interface may use tuples to pack two or more return types. Some of the better candidates for dual interfacing include Standard Library functions that return only char * but not std::string. For example, the getenv() function retrieves an environment variable and returns its value in the form of a C-string. In this case, overloading can do the trick:
char * getenv(const char * name); //existing version //hypothetic overloaded version const std::string& getenv(const std::string name);
However, if the function can't use different arguments to play this trick, tuples can save the day. For example, a function that translate a file name to its equivalent FILE * and a file descriptor can't rely on overloading because its parameter doesn't change, only the return type. POSIX often solves this problem by defining multiple functions with slightly different names:
int traslatefile(const char * path); FILE * ftraslatefile(const char * path);
Using a tuple can solve this problem neatly:
typedef tuple <int, FILE *> file_type; file_type translatefile (const char *);
Summary
Tuple types are only one of many new facilities that are being added to the Standard Library. The fact that very minimal core changes, if any, are needed to support the new proposals shows the foresight of C++ designers. Consequently, the new facilities can be neatly integrated in existing code without causing conflicts or design changes to existing code.