hat were you doing during the morning hours (EST) of July 13th 2009? On that auspicious day, in a dramatic vote, the C++ standards committee decided to remove concepts from C++0x. Undoubtedly, this resolution will have a huge impact on C++. In this column I will outline the causes of concepts' failure, discuss the lessons from this unprecedented event, and try to predict how it will affect the future of C++.

Immaculate Concepts

The main impetus for adding concepts to C++ was to allow template designers to precisely specify requirements and constraints on and among types. The problem was how to design a constraints mini-language that would be simple and intuitive on the one hand, and complete and efficient on the other hand. To demonstrate the problem that concepts were supposed to solve, consider the function template min() . It imposes certain implicit requirements on the type T:

template<typename T> const T& min(const T& x, const T& y) { return x < y? x : y; }

T must be a type that has a less-than operator ( < ) to compare two values of type T, and the result of which must be convertible to a Boolean value. In C++03 it's difficult to express these requirements in a clear and bullet-proof manner. Bjarne Stroustrup and Gabriel Do Reis presented the first concepts paper in 2003 (other committee members contributed to this endeavor later). At first, it seemed as if concepts ticked the right boxes. Here's a modified min() function that uses concepts to express the constraints on T:

concept LessThanComparable<typename T> { bool operator<(const T& x, const T& y); } template<typename T> requires LessThanComparable<T> const T& min(const T& x, const T& y) { return x < y? x : y; }

Author's Note: The examples are quoted from Douglas Gregor's excellent introduction to concepts.

If C++ templates had to deal only with simple cases like min() , the design of concepts would be a cinch. However, the C++ Standard Library consists of far more complex templates—containers that impose certain requirements on their elements, smart pointers with peculiar ownership semantics, algorithms that must meet certain performance limits, various categories of iterators—you name it. That is why the authors have been refining the concepts specification for more than seven years.

After several iterations, the concepts proposal forked off in two different directions (the technical differences between the two proposals will not be discussed here). A compromise was reached at the October 2005 meeting in Mont-Tremblant, Canada; the two competing proposals would be merged into an integrated concepts proposal known as the "Mont-Tremblant compromise."

Off the record, some committee members viewed the Mont-Tremblant compromise as the watershed—the integrated concepts proposal had simply turned into an incoherent monster. Debates about whether the imminent C++ standard should include a conceptualized Standard Library heated up. While some of the problems with concepts were resolved promptly, each new day led to the discovery of additional problems and disagreements. With serious efforts, the committee managed to approve the C++0x Committee Draft (which included concepts) in September 2008. However, in recent months, the criticism and doubts concerning concepts reached a boiling point. The last straw was probably Stroustrup's latest concepts paper, which added more fears and doubts. The concepts-related threads on the committee's reflectors (list servers) pointed out that concepts were "untried, risky, incomplete and controversial." Concerns about compile-time and runtime overhead were also voiced. As the Frankfurt meeting got closer, these voices became harsher and louder.

Two Tough Choices

The distrust and antipathy toward concepts paved the way to voting this feature out of C++0x. There was one huge problem with this decision though: concepts were already pervasive in the Committee Draft (CD). Almost every paragraph and code listing involving templates uses concepts directly or indirectly. Worse yet, many new features that have been accepted into C++0x in recent years presuppose concepts. Removing concepts from the standard will require a massive excision operation that might kill the patient. But what other choices did the committee have?

Leaving concepts in situ wasn't a better choice. Even the authors agree that the current concepts specification isn't complete, and that perfecting it would take "several more years." However, they consider the current proposal "good enough for now." Furthermore, they insist that the outward complexity of concepts is misleading—the underlying model is "good enough;" it's only the surface complexity (what the user has to write) that needs fixing. Considering that concepts have already taken seven years of precious committee time, no one was willing to spend five more years or so on refining the surface complexity, or indeed any other concepts complexity. The cruel choice was thus between a painful excision, and asymptotic refinement of concepts. On the afternoon of July 13th the die was cast: Concepts were voted out of C++0x by a decisive margin.

An Unprecedented Event

Unlike other self-contained features that usually have no huge impact on C++ as a whole ( nullptr for example), the removal of concepts amounts to a landslide, and will probably lead to a witch hunt. Committee members and the C++ community will want answers. It appears that the committee's limited resources were wasted on a feature that failed, while at the same time, other critical C++0x features such as multithreading and garbage collection didn't get enough attention.