ISO C++ committee draft

Following the recent meeting of the ISO C++ standards committee, Working Group 21 (WG21) in Bristol, UK, a number of proposals have been accepted into the ‘Committee Draft’ of the next standard, currently scheduled for next year (“C++14”).

Although this is a ‘bug fixes and minor update’ revision of the standard, it contains some improvements that I know will show significant improvement in some areas. Generic lambdas, generalized captures and return type deduction for normal functions, for example, will enable creation of code that is less brittle in the face of type changes, and also allow things that weren’t possible without hacks (e.g. moving unique_ptr objects into lambdas).

Herb Sutter has written up his trip report, which shows an overview of the changes, and below is a list I have compiled of the accepted papers. I wrote the original for my team, so it is ordered by level of relevance/benefit to our own work or my own interest, and I have given less attention to detail for the proposals I don’t see affecting me/us. I will gladly accept suggested corrections and omissions for the list.

[April 26th] Michael Wong has also written a trip report covering some of the discussions and rationale. This is part 1 (Language).
[April 27th] Reddit discussion of  some of the new facilities.
[April 30th] Part 2 (Library) of Michael Wong’s trip report.
[May 1st] Part 3 (Concurrency) of Michael Wong’s trip report.
[Sep 25th] The first Committee Draft of the C++14 standard, N3690, is available here.

N3656 make_unique

Proposes the missing unique_ptr analogue for make_shared. There are 3 overloads: 1 for a single object with argument pack that is forwarded to the object constructor, and 2 for arrays, one of which is deleted to ensure it is used correctly (it takes a single argument: the array size, so cannot be used for a fixed-size array). The implementation of the single object overload matches that suggested by Herb in GotW 102.

N3638 Return type deduction for normal functions

This adds the ability to use auto for any function’s return type, with the same effect as exists now for lambdas, i.e. deduce the return type from the function’s implementation. For both normal functions and lambdas the requirement that the implementation be of the form return expression; is relaxed, and the deduction even works for recursive functions as long as a single type is deducible!

auto sum(int i) {
  if (i == 1)
    return i;  // return type deduced to int
  else
    return sum(i-1)+i; // ok to call it now
}

Return type deduction is not supported for virtual functions.

N3648 Wording Changes for Generalized Lambda-Capture

Adds lambda captures of the form identifier initializer and &identifier initializer, which both behave like a declaration of the same form preceded by auto. The paper is standardese only, but N3610 has a more readable description.

int x = 4;
auto y = [&r = x]() {...}; // equivalent to auto& r = x

// shows moving an object into a capture variable, as well as the capture
// identifier capturing from and hiding the same name from outer scope.
std::unique_ptr p( new int(42) );
auto z = [p = std::move(p)]() {...};

N3649 Generic (Polymorphic) Lambda Expressions (rev3)

Enables ‘templated’ lambdas, and without an angle bracket or template in sight; marvellous!

auto Identity = [](auto a) { return a; };

In addition this change will allow ‘universal references’, parameter packs, and perfect forwarding:

template< class T >
auto make_factory() { // using N3638 return type deduction
  return []( auto&&... args ) {
    return std::unique_ptr( new T( std::forward< decltype(args) >(args)... ));
  }
}

N3659 Shared locking in C++

This provides shared_mutex, and shared_lock for non-exclusive (‘read’) locking, with unique_lock continuing to provide the exclusive (write) locking as it does today.

N3655 Transformation traits redux, v2

This is a ‘convenience’ proposal to simplify usage of the ‘transformation traits’ that produce one type from another, such as add_lvalue_reference.

With today’s library you must write typename add_lvalue_reference<T>::type to use the facility, whereas the proposal adds a template alias interface enabling add_lvalue_reference_t<T>. Note the trailing _t there: each of the transformation traits gains an alias with the same name transformation.

Although I’m sure some will deem these additions too trivial to fill pages of the standard with – indeed section 4, which adds the same treatment for the other traits, was not accepted for this reason – they do clean up syntax particularly where transformations are nested, and I will be using them myself. The paper includes the additions for all traits, so those who wish can use them immediately including the section 4 transformation aliases.

N3672 The standardisation of Boost.Optional

What it sounds like, with some differences to the current Boost.Optional implementation, particularly useful being the addition of move support.

From the paper, “The basic usage of optional can be illustrated with the following example.”

optional<int> str2int(string);    // converts int to string if possible

int get_int_form_user()
{
  string s;

  for (;;) {
    cin >> s;
    optional<int> o = str2int(s); // 'o' may or may not contain an int
    if (o) {                      // does optional contain a value?
      return *o;                  // use the value
    }
  }
}

N3662 C++ dynamic arrays (dynarray)

A kind of std::vector/std::array hybrid; has a capacity fixed on construction (unlike vector) that is not part of the type (unlike array). This provides much-needed sequence container operations over a raw array where we don’t want a different type, or cannot fix size at compile-time.

// construct
std::dynarray<int> ints(5, 42); // the sequence {42,42,42,42,42}
auto another(ints);             // copy-constructed sequence
std::dynarray<int> empty(0);    // empty sequence {}

// size & unchecked element access
for (int i=0; i < ints.size(); ++i)
  ints[i] = i;

ints.at(10) = 10; // throws std::out_of_range

// front/back
ints.front() = 5;
ints.back() = 5;

// sequence iteration output "25 1 25 3 25"
std::copy( ints.begin(), ints.end(), std::ostream_iterator(std::cout, " "));

// contiguous storage access
int* data = another.data();
another.fill(0);

N3639 Runtime-sized arrays with automatic storage duration (rev5)

Based on the recent addition of Variable-Length Arrays (VLAs) in C11, this allows e.g. int a[n]; where n has a runtime value, and restricts a to automatic storage duration. The dynarray proposal (N3662) allows for the freestore-based equivalent.

N3652 Relaxing Constraints on constexpr Functions

Allow some declarations, if, switch, for, while, do-while, and mutation of locally-scoped objects in constexpr functions.

N3668 exchange() utility function (rev3)

Specifies T std::exchange(T& old, U&& new) that updates old to new and returns old‘s original value, similar to the facilities provided for atomics.

N3651 Variable templates

Enables type-parameterized constants e.g. for different representations of pi: pi<double>, pi<float> and, God forbid, pi<int> 😀

N3654 Quoted strings (rev2)

Allows for fixing the inconsistency in the following:

std::stringstream ss;
ss << "Hello world";
std::string in;
ss >> in; // 'in' is "Hello" instead of "Hello world"

N3642 User-defined literals for standard library types

Adds ‘user-defined’ (albeit defined by the library…) literals for std::basic_string (e.g. "blah"s), std::chrono::duration members (e.g. 21min, 42ms), plus binary and complex numbers.

Other proposals

As Herb’s trip report, and the comments beneath it, show, additional proposals have been worked on during the meeting, in particular N3505, a Boost.Filesystem (v3)-based library, is looking good for release in parallel, along with a networking library and N3580 “concepts lite”.

One of the even more exciting things that I hope will truly revolutionise how we use C++ is the ‘modules’ proposal. This formalises package (module) management to make the compiler aware of them, and neatly combines the facilities that are currently rather clunkily provided by namespaces and headers. If my understanding is correct, this will also provide a basis for much faster builds as the include vs. forward declare, and exposure of implementation of class/function templates in headers become non-issues that need not be considered. According to Herb this is being worked on by the Clang guys and “the intent is to issue a Modules technical specification as soon as it’s ready”. Hurrah!

Finally, a massive thanks to all those at the coalface for the work that went into these proposals and last week. The results are impressive, and the scale of accepted proposals stretches the bounds of the ‘bug fixes and minor update’ description. Roll on 2012 🙂

This entry was posted in Uncategorized and tagged , , , , . Bookmark the permalink.

4 Responses to ISO C++ committee draft

  1. Nate Kohl says:

    Did you forget the template parameter on std::dynarray?

  2. foo bar says:

    I do not believe optional can be used without the type parameter

    • robdesbois says:

      Ah yes, I forgot to encode the ‘<‘ and ‘>’ characters after pasting the example – thanks.

Leave a reply to robdesbois Cancel reply