New adopted paper: N3656, make_unique (Revision 1) -- Stephan T. Lavavej

Note: This paper was adopted into draft C++14 on Saturday at the Bristol UK ISO C++ meeting.

A new WG21 paper is available. A copy is linked below, and the paper will also appear in the next normal WG21 mailing. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: N3656.txt

Date: 2013-04-18

make_unique (Revision 1)

by Stephan T. Lavavej

The paper includes source code for a complete implementation.

New adopted paper: N3668, exchange() Utility Function, revision 3 -- Jeffrey Yasskin

Note: This paper was adopted into draft C++14 on Saturday at the Bristol UK ISO C++ meeting.

A new WG21 paper is available. A copy is linked below, and the paper will also appear in the next normal WG21 mailing. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: N3668

Date: 2013-04-19

exchange() utility function, revision 3

by Jeffrey Yasskin

Excerpt:

Atomic objects provide an atomic_exchange function ([atomics.types.operations.req]p18) that assigns a new value to the object and returns the old value. This operation is also useful on non-atomic objects, and this paper proposes adding it to the library. The benefit isn't huge, but neither is the specification cost.

template<typename T, typename U=T>
T exchange(T& obj, U&& new_val) {
  T old_val = std::move(obj);
  obj = std::forward<U>(new_val);
  return old_val;
}

For primitive types, this is equivalent to the obvious implementation, while for more complex types, this definition

  • Avoids copying the old value when that type defines a move constructor
  • Accepts any type as the new value, taking advantage of any converting assignment operator
  • Avoids copying the new value if it's a temporary or moved.

New adopted paper: N3649, Generic (Polymorphic) Lambda Expressions (R3) -- Vali, Sutter, Abrahams

Note: This paper was adopted into draft C++14 on Saturday at the Bristol UK ISO C++ meeting.

A new WG21 paper is available. A copy is linked below, and the paper will also appear in the next normal WG21 mailing. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: N3649

Date: 2013-04-19

Generic (Polymorphic) Lambda Expressions (Revision 3)

by Faisal Vali, Herb Sutter, Dave Abrahams

Excerpt:

This document revises wording for generic lambda expressions as described in N3559: Proposal for Generic (Polymorphic) Lambda Expressions (Revision 2) and as approved by EWG and which should be referenced for further detail.  Today’s C++11 lambda expression concisely creates an instance of a class having a non-template function call operator.  We propose a pure extension of C++11 lambda syntax that creates an instance of a class having a function call operator template. 

Here follow some examples of the proposed syntax extension in use:

// 'Identity' is a lambda that accepts an argument of any type and
// returns the value of its parameter. 
auto Identity = [](auto a) { return a; };
int three = Identity(3);
char const* hello = Identity("hello");

// Conversion to function pointer for capture-less lambdas
int (*fpi)(int) = Identity;
char (*fpc)(char) = Identity;

New adopted paper: N3651, Variable Templates (Revision 1) -- Gabriel Dos Reis

Note: This paper was adopted into draft C++14 on Saturday at the Bristol UK ISO C++ meeting.

A new WG21 paper is available. A copy is linked below, and the paper will also appear in the next normal WG21 mailing. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: N3651

Date: 2013-04-19

Variable Templates (Revision 1)

by Gabriel Dos Reis

Excerpt:

C++ has no notation for parameterized constants as direct as for functions or classes. For instance, we would like to represent the mathematical constant with precision dictated by a floating point datatype

template<typename T>
constexpr T pi = T(3.1415926535897932385);

and use it in generic functions, e.g. to compute the area of a circle with a given radius:

template<typename T>
T area_of_circle_with_radius(T r) {
    return pi<T> * r * r;
}

The types of variable templates are not restricted to just builtin types; they can
be user defined types. ...

This report proposes a simple extension to C++: allow variable templates. It makes definitions and uses of parameterized constants much simpler, leading to simplified and more uniform programming rules to teach and to remember.

New adopted paper: N3652, Relaxing Constraints on constexpr Functions -- Richard Smith

Note: This paper was adopted into draft C++14 on Saturday at the Bristol UK ISO C++ meeting.

A new WG21 paper is available. A copy is linked below, and the paper will also appear in the next normal WG21 mailing. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: N3652

Date: 2013-04-18

Relaxing constraints on constexpr functions

by Richard Smith

This is a major extension to constexpr. Excerpt:

This paper describes the subset of N3597 selected for inclusion in C++14, relaxing a number of restrictions on constexpr functions. These changes all received overwhelmingly strong or unopposed support under review of the Evolution Working Group. It also incorporates Option 2 of N3598.

The changes selected by the Evolution Working Group were:

  • Allow declarations within constexpr functions, other than:
       static or thread_local variables
       uninitialized variables
  • Allow if and switch statements (but not goto)
  • Allow all looping statements: for (including range-based for), while, and do-while
  • Allow mutation of objects whose lifetime began within the constant expression evaluation.

In addition, in discussion of N3598, Option 2 was selected, which removes the rule that a constexpr non-static member function is implicitly const.

New adopted paper: N3648, Wording Changes for Generalized Lambda-Capture -- Vandevoorde, Voutilainen

Note: This paper was adopted into draft C++14 on Saturday at the Bristol UK ISO C++ meeting.

A new WG21 paper is available. A copy is linked below, and the paper will also appear in the next normal WG21 mailing. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: N3648

Date: 2013-04-17

Wording Changes for Generalized Lambda-Capture

by Daveed Vandevoorde and Ville Voutilainen

NOTE: This paper is standardese only. For a description of the feature, see N3610, Generic Lambda-capture Initializers, Supporting Capture-by-move.

New adopted paper: N3638, Return Type Deduction for Normal Functions -- Jason Merrill

Note: This paper was adopted into draft C++14 on Saturday at the Bristol UK ISO C++ meeting.

A new WG21 paper is available. A copy is linked below, and the paper will also appear in the next normal WG21 mailing. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: N3638

Date: 2013-04-17

Return type deduction for normal functions

by Jason Merrill

Excerpt:

Any C++ user introduced to the C++11 features of auto, lambdas, and trailing return types immediately wonders why they can't just write auto on their function declaration and have the return type deduced. This functionality was proposed previously in N2954, but dropped from C++11 due to time constraints, as the drafting didn't address various questions and concerns that the Core WG had. I have now implemented this functionality in GCC, and propose to add it to C++14. I discuss some of the less obvious aspects of the semantics below.

This proposal also resolves core DRs 975 (lambda return type deduction from multiple return statements), 1048 (inconsistency between auto and lambda return type deduction), and 1588 (deducing cv-qualified auto).

Note that this paper also allows lambdas (not just functions) with multiple return statements to have their return type deduced. Examples in the paper include multiple returns, recursion, and more:

auto iterate(int len)                        // return type is deduced as int
{
  for (int i = 0; i < len; ++i)
    if (search (i))
      return i;
  return -1;
}

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

template <class T> auto f(T t) { return t; } // return type deduced at instantiation time

[]()->auto& { return f(); }                  // return a reference

New adopted paper: N3662, C++ Dynamic Arrays (dynarray) -- Lawrence Crowl, Matt Austern

Note: This paper was adopted into draft C++14 on Saturday at the Bristol UK ISO C++ meeting.

A new WG21 paper is available. A copy is linked below, and the paper will also appear in the next normal WG21 mailing. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: N3662

Date: 2013-04-19

C++ Dynamic Arrays

by Lawrence Crowl and Matt Austern

See also related paper N3662, "Runtime-Sized Arrays with Automatic Storage Duration (Revision 5)"

Excerpt:

Instead of adopting C variable-length arrays, we propose to define a new facility for arrays where the number of elements is bound at construction. We call these dynamic arrays, dynarray. In keeping with C++ practice, we wish to make dynarrays usable with more than just automatic variables. But to take advantage of the efficiency stack allocation, we wish to make dynarray optimizable when used as an automatic variable.

 

New adopted paper: N3639, Runtime-Sized Arrays with Automatic Storage Duration (Rev5) -- Jens Maurer

Note: This paper was adopted into draft C++14 on Saturday at the Bristol UK ISO C++ meeting.

A new WG21 paper is available. A copy is linked below, and the paper will also appear in the next normal WG21 mailing. If you are not a committee member, please use the comments section below or the std-proposals forum for public discussion.

Document number: N3639

Date: 2013-04-16

Runtime-sized arrays with automatic storage duration (revision 5)

by Jens Maurer

See also related paper N3662, "C++ Dynamic Arrays (dynarray)"

Excerpt:

Sometimes, a user wishes to allocate a local array whose size is not known at compile-time, but at runtime only. Nonetheless, the array's size will remain unchanged during the lifetime of the array.

Examples are

  • interfacing with the readv/writev POSIX system calls
  • small runtime-sized data structure to apply STL algorithms calls
  • ...

This paper proposes to add local runtime-sized arrays with automatic storage duration to C++, for example:
void f(std::size_t n)
{
   int a[n];
   for (std::size_t i = 0; i < n; ++i)
       a[i] = 2*i;
   std::sort(a, a+n);
}

Traditionally, the array bound "n" had to be a constant expression (see 8.3.4 dcl.array). For local arrays with automatic storage duration, this paper proposes to lift that restriction. The syntax is intended to be the same as that used for C99 variable length arrays (VLAs), except that implementation support for VLAs is optional in C11 and aggregate initialization is not supported in C.

As a design guideline, the same rules should apply to "new T[n]" and a local array "T a[n]", except that arrays of zero size are only supported for new.

There is well-established existing practice with gcc, Clang, and Intel C++ all implementing a similar, if not identical feature. In fact, Douglas Gregor reported in c++std-ext-12553 on 2012-01-30: "Users really seem to want this feature. It's a fairly common extension, and when we tried to ban it out of principle (in Clang), our users reacted *very* strongly."

Trip Report: ISO C++ Spring 2013 Meeting

This afternoon in Bristol, UK, the ISO C++ standards committee adopted generic lambdas, dynamic arrays (an improved version of C99 VLAs), variable templates, reader/writer locks, make_unique, optional<T>, standard library user-defined literals, and a number of other language and library improvements -- and approved the result as the feature-complete Committee Draft (CD) of Standard C++14 to be distributed for its primary international review ballot.

In addition to completing the C++14 CD document, the committee also made progress on three additional important parallel specifications that are on track to be published around the same time as C++14:

  • File system library (draft), based on Boost.FileSystem version 3.
  • Networking library, small at first and regularly extended.
  • "Concepts Lite" language extensions (draft), to express template constraints and improve template usability and error messages.

Together these mark the C++ committee’s main planned deliverables for 2014. Updated papers and an updated working draft will be available soon.

Meeting Highlights

Bristol saw a recent-record number of technical papers (160), attendees (over 100), parallel technical sessions (typically six or more subgroups meeting at once), and many overlapping evening sessions – including formal sessions that ran past midnight at least twice to resume again at 08:30.

C++14: Bug Fixes + Minor Update

C++14 is primarily a bug-fix release, but also includes new features that were ready including a number that developers have been asking for the standard to support. With the CD document contents now set to be balloted this summer, we for the first time know the shape and feature set of C++14.

To provide just a sampling, here are a few quick examples of some of the newly added features.

make_unique

One of the smallest additions is actually great in its impact. It's make_unique:

auto u = make_unique<some_type>( constructor, parameters, here );

The reason make_unique has important impact is that now we can teach C++ developers to mostly never use explicit new again. In C++11 we already could teach to never use owning raw pointers and explicit delete again, except in rare cases that are hidden inside a class in order to do something like implement a low-level data structure. However, we could not teach to never write new because although make_shared was provided to create a shared_ptrnew was still needed to create a unique_ptr. Now, instead of “new”, write make_unique or make_shared.

With draft C++14, we can say simply: Don't use owning raw pointers, new, and delete, except rarely when implementing low-level data structures. Allocate with make_unique or make_shared, use weak_ptr where appropriate to break cycles, and don't worry about dangling pointers in C++ again.

Generic lambdas

Lambdas will now support auto as a type name. This is convenient when the type is tedious to spell out, and is especially nice in generic code where you want the same lambda object to be usable with a variety of types. For example:

vector<int> v;
vector<shared_ptr<some_type>> index;   // stores pointers to objects

// C++11:
//
for_each( begin(v), end(v), []( decltype(*begin(v))& x ) { cout << x; } );

sort( begin(index), end(index), []( shared_ptr<some_type> const& p1, shared_ptr<some_type> const& p2 ) { return *p1 < * p2; } );

auto get_size = []( unordered_multimap<wstring, list<string>> const& m ) { return m.size(); };

// C++14 draft:
//
for_each( begin(v), end(v), []( auto& x ) { cout << x; } );

sort( begin(index), end(index), []( auto const& p1, auto const& p2 ) { return *p1 < * p2; } );

auto get_size = []( auto const& m ) { return m.size(); };
  // bonus: this now works with any container that supports .size()

Lambda generalized capture

Lambdas will now be able to capture by move, and define new local variables in the lambda object. For example:

auto u = make_unique<some_type>( some, parameters );  // a unique_ptr is move-only

go.run( [ u{move(u)} ] { do_something_with( u ); } ); // move the unique_ptr into the lambda

Variable templates

These can perhaps be best illustrated with an example taken right from the draft standard text (comments added).

// Write pi once for every possible type
template<typename T>
constexpr T pi = T(3.1415926535897932385);

// Sample use
template<typename T>
T circular_area(T r) {
    return pi<T> * r * r;
}

Dynamic Arrays

Draft C++14 now has fixed- but runtime-sized arrays of two kinds: in the language, and as a dynarray<T> library.

In the language, draft C++14 now allows stack-based arrays to have a size determined at run time:

void f(std::size_t n)
{
   int a[n];

   ...

}

Note that this is not the same as C99 variable length arrays (VLAs), and that the C11 standard has made VLAs conditionally-supported so that they are no longer part of portable C required in a conforming C compiler. In particular, C++ explicitly not does support the following features from C99 VLAs which C++ feels are not desirable:

  • multidimensional arrays, where other than the top level has a runtime bound (in analogy, the array form of new expressions doesn't support that either)
  • modifications to the function declarator syntax
  • sizeof(a) being a runtime-evaluated expression returning the size of a
  • typedef int a[n]; evaluating n and passing that through the typedef

In addition to stack-based runtime-sized arrays, we now also have a dynarray<T> container in the standard library. The two features are similar, but with a few key differences: Both permit efficient allocation on the stack or on the heap, at the discretion of the implementation, but dynarray<T> can additionally be used as a non-stack variable and in those cases will use the heap, it is inspectable with decltype, and it supports zero-sized arrays.

optional<T>

To highlight just one more of the new features and changes, we have an evolution of Boost’s optional type. An example tells most of the story:

    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
    }

On Deck: Also Targeting the '14 Timeframe

And let's end with a template checking with Concepts Lite teaser... if you write this today, what do you get?

template<typename Cont>
void sort(Cont& c);

list<int> lst = { 1, 3, 2, 4 };
sort(lst);                        // ???

Impenetrable template diagnostics. At considerable length.

What we want:

template<Sortable Cont>
void sort(Cont& c);

list<int> lst = { 1, 3, 2, 4 };   
sort(lst);                        // "error: lst is not Sortable"

An implementation of the above, with about that error message, already exists.

Beyond that, consider even a "terse syntax" that would be especially helpful with generic lambdas:

void sort(Sortable& s);           // possible syntax: implicit function template

int main() {                      // and now that we have generic lambdas in the language...
    auto mysorter = [](Sortable& s){ /*...*/ }; // possible syntax
                                  // ... we'll surely want to constrain those too
}

Interestingly, that last example shows some nice, type-checked, robust and fully generic template code, with nary a <> in sight.

All of this is grist for the Concepts Lite Technical Specification, currently targeted for completion and publication next year.

Wrapping Up

Updated papers for these and other features, as well as an updated working draft, are expected to be available in the next two or three weeks.

Thanks again to the many committee members who worked tirelessly in preparation for this meeting, and around the clock all this past week, to achieve this milestone!