Archive for February, 2007

Tying Down the Details: The Google Concepts Meeting

February 27, 2007

Last week, around 15 members of the ISO C++ standards committee met for two days at Google to discuss the concepts proposal and tie down various details. Some syntax has changed, some semantics has changed, but the vast majority of the concepts proposal is exactly the same as it was.

We made the following syntactic changes, all of which have been implemented in the latest development version of ConceptGCC (in Subversion):

– The “where” keyword has been changed to “requires”, e.g.,

template<typename T>
requires LessThanComparable<T>
const T& min(const T& x, const T& y);

– The && syntax used to separate requirements in a where clause (now a “requires clause” or “requirements clause”) has been replaced with “,”. The requires clause is now just a comma-separate list of requirements, and the list has (optional!) parentheses around it. An example:

template<typename Iter, typename T>
requires InputIterator<Iter>, EqualityComparable<Iter::value_type, T>
Iter find(Iter first, Iter last, const T& value);

– The use of “where” inside function bodies, which was never supported by ConceptGCC, has been removed.

– “late_check” now comes before “template” in the template header. ConceptGCC already parsed late_check in this way; now, it’s official.

ConceptGCC implements these changes, and warns about the use of the “where” keyword and && syntax. These warnings will remain for a few versions, until existing code can be ported to the new syntax.

There were a few semantic changes, which have not yet made it into GCC:

– It is no longer correct to call an unconstrained template from a constrained one. Use late_check if you need to do this.

– Name lookup in requires clauses will use lexical scoping. This has been the default in ConceptGCC since its creation, but we supported other name lookup approaches. Those are gone. ConceptGCC also includes a warning when a using declaration hides a name in the requires clause (enabled by -Wall or -Wsignature-shadow). See the discussion of name lookup and std::swap for the motivation behind this warning.

– Name lookup of associated types inside template parameters (e.g., Iter::value_type) now works regardless of whether the requirement comes from the template header or from the requires clause. ConceptGCC has had two modes for a while; we’ve removed the only-look-in-inline-requirements mode.

Along with these changes, I’ve managed to fix several bugs in ConceptGCC that were causing build problems on various architectures. The changes themselves are uninteresting; what matters is that the development version of ConceptGCC should build without problems.

Decltype and Rvalue References and Variadic Templates, Oh My!

February 15, 2007

Over the last week, I have merged patches into ConceptGCC that introduce complete support for three complementary C++0x features: decltype, rvalue references, and variadic templates.

decltype allows one to compute the type of an arbitrary expression. It’s like the much-requested typeof operator, but the new name reflects the fact that we’re getting the “declared type” of variables. This facility is useful, for example, if one wants to forward to another function and return its value, because decltype allows us to declare our return type based on the forwarding expression.

Rvalue references allow one to implement “move semantics” for types, which can drastically improve performance be moving resources from a temporary that will be destroyed, rather than copying those resources. For example, returning a temporary std::vector from a function would become a fast, O(1) operation, rather than a full O(N) copy operation. Rvalue references also let us forward arguments properly, preserving the lvalue- and rvalue-ness of the arguments.

Variadic templates allow one to write templates that take an arbitrary number of template parameters. This leads to natural implementations of class templates like tuples and even type-safe versions of “printf”.

Taken together, these features allow us to implement libraries that deal with function objects that are much easier to use than the current forms (of, e.g., Boost’s Function and Bind libraries, both of which are part of C++0x and TR1), require far less code to implement, and compile much faster.

Clarification: The rvalue references patch that I’ve merged into ConceptGCC is not my own. I used Russell Yanofsky’s rvalue references patch, with a few minor fixes. I’m hoping that his amended patch can go into GCC 4.3.0’s experimental C++0x mode.