Toronto ISO C++ Committee Meeting Trip Report
Erich Keane erich.keane@verizon.net
C++ 17 Status
- Was published as a "Draft International Standard" at the Kona meeting.
- Ballots sent out to the "ISO National Bodies"
- Ballot Voting closes in early September
- If Unanimously accepted, automatically becomes the "International Standard" (no more Draft!)
- Otherwise, a vote of the National Body Chairs will be held in November's New Mexico meeting. If consensus is reached, becomes the "International Standard"
Evolution(EWG) Report:
- Where I spent my whole time.
- Tons of work! Only including stuff that didn't make it through 'core'.
- Not including things that were rejected, unless super interesting.
P0132R0: Non-throw container Ops:
- Discussed approach for push_back/etc stuff to have no throw alternatives. bool push-back(nowthrow_t, const T&); vs bol push_back_nowthrow(const T);
- Referred to Library Evolution (LEWG) with encouragement.
P0702R0:
vector v{vector{1,2}};
- What is the meaning of the above? Is this an initializer-list or a move/copy call?
- Encouraged "copy/move" instead of init list.
tuple t {tuple {1,2}}; // decltype(t) is tuple<int,int> as of Kona
// decltype(v) was unclear. Previously could be vector<vector<int>>
// Directions to Core WG to make a Defect against 17 and be vector<int>
vector v{vector{1,2}}; P0654R0:explict structs
- A struct that requires all fields to be initialized.
- Decided against.
explicit struct E {
Color c;
int r;
};
E e; // error, doesn't init everything.
E e1{Color::red}; // Same.
P0627R1:Unreachable
- Standardize "unreachable"
//Suggested as an attribute, similar to fallthrough:
void f() {
switch (something) {
default:
[[unreachable]]; // note needs semicolon.
case 1:
//...
}
}
// Guidance to change to a function:
void f() {
switch (something) {
default:
std::unreachable("abc"); // string optional.
case 1:
//...
}
}Modules + Concepts
- Massive discussions.
- Minor changes to Modules suggested.
- Concepts lost 'bool' keyword in definition.
- Semantic constraint matching changed (when are 2 concepts related?).
- Concepts had 'terse' syntax removed.
- Further work on terse syntax strongly supported.
P0238R1: Terser Lambdas?
- Proposed some changes to lambdas, altering the syntax.
- Guidance to follow up, but no real decisions.
[](auto const& s) => s == 2;
// Equivalent to:
[](auto const& s) noexcept(s == 2) -> decltype((s==2)) {
return s == 2;
}P0624R0: Default ctor stateless Lambdas:
- Lambdas cannot be put into a map due to lack of a default ctor. Also not copy-able.
- Guidance to enable default ctor, copies for stateless.
auto greater = [](auto a, auto b) {return a > b;};
std::map<std::string, int, decltype(greater) map; // illegal :(
decltype g;
g = greater; // meaningless, but illegal.P0634R0: Down with typename
- Relax need for 'typename' when the compiler 'knows'.
// why typename necessary? only a type is legal.
template<class T> struct D : typename T::B {};
static_cast<typename T::B>(...);
template<typename T>
void foo(T t) -> typename T::B {...};
// This:
template<class T> typename T::R f(typename T::P);
template<class T> struct S {
using Ptr = typename PtrTraits<T>::Ptr;
typename T::R f(typename T::P p) {
return static_cast<typename T::R>(P);
}
auto g() -> typename S<T*>::Ptr;
};
//Becomes:
template<class T> T::R f(T::P);
template<class T> struct S {
using Ptr = PtrTraits<T>::Ptr;
T::R f(T::P p) {
return static_cast<T::R>(p);
}
auto g() -> S<T*>::Ptr;
};P0619R1: Review Deprecated Things
- 3 Items in Annex D for EWG to look into:
// Exception specifiers:
void foo() throw() {} // throw() deprecated
// Guidance to delete.
// Redecl of static constexpr data members:
struct A {
static constexpr int n = 5;
};
constexpr int A::n; // deprecated, stays that way.
// Implicit copy assign/construct.
// copy/assign/dtor definition don't delete eachother:
struct S {
S(const S&); // copy assignment still implicit
S(S&&);// move assignment deleted.
};P0614R0: range-for init
- Add C++17 while/if initializer to range-fors.
// Fixes 'dangling r-value' issue here:
for (T thing = f(); auto& x : thing.times()) {}
// Allows this:
for (size_t i = 0; const auto& x : foo()){
++i;
//...
}
// To Core in NM.P0572R1: bit_sizeof/bit_offsetof
- Guidance to add these two as operator-like functions.
struct S {
unsigned A : 5;
unsigned B : 4;
unsigned C : 3;
};
//bit_sizeof(S::B) == 4
//bit_offsetof(S, C) == 9
P0639R0: constexpr_containers?
- Existing proposals for constexpr_vector
- Should we abandon this, and see if we can make existing containers things legal to be constexpr?
- Guidance to 'work more on it':
- Make a constexpr-new/delete version.
- Make placement-new constexpr in certain situations
- Alter std::allocator to use these new features.
P0665R0: Class template specialization out of NS:
- Currently, class template specializations need to happen in the original namespace. Lets relax that:
// guidance to encourage further work:
namespace my {
struct tuple_like { /* ... */ };
template <>
struct ::std::hash<tuple_like> { /* ... */ };
template <>
struct ::std::tuple_size<tuple_like> { /* ... */ };
template <>
struct ::std::tuple_element<tuple_like> { /* ... */ };
/* ...other declarations in my namespace... */
}SG7 (Reflection) Report:
- Extensive discussion on Static reflection of Functions
- A bunch of stuff already exists.
- Discussion of 'metaclasses', encouraged work, but not approach.
Final Votes From Plenary
- Many now go into the "Working Draft" for C++2a.
- Comments/papers are still welcome to fix/improve.
- Many have more improvements in the pipeline.
- "TS" : Technical Specification
- "PDTS" : Preliminary Draft for TS
P0683R1: Bit-field default init:
- Was previously left out due to complexity/parse issues.
int a;
struct S {
int x : 8 = 42; // Allow this!
int y : true ? 8 : a = 42; // This and the below are troublesome
int z : 1 || new int {0};
};
// Solution is to 'Max Munch'
// From Standard:
int a;
const int b = 0;
struct S {
int x1 : 8 = 42; // OK; "= 42" is brace-or-equal-initializer
int x2 : 8 { 42 }; // OK; "{ 42 }" is brace-or-equal-initializer
int y1 : true ? 8 : a = 42; // OK; brace-or-equal-initializer is absent
int y2 : true ? 8 : b = 42; // error: cannot assign to const int
int y3 : (true ? 8 : b) = 42; // OK; "= 42" is brace-or-equal-initializer
int z : 1 || new int { 0 }; // OK; brace-or-equal-initializer is absent
};P0409R2: [=, this] capture
- Clarify capture rules in the case of default-copy in lambdas.
void Type::foo() {
[=] () {}; // captures 'this' by pointer
[=, *this] () {}; // captures 'this' by copy.
[=,this]() {} // same as 1st, but now explicit.
}P0329R4: Designated Inits
- C has named initializers, lets get them too (sorta).
struct A { int x; int y; int z; };
A a{ .x = 1, .z = 2}; // Now legal!
// Limitations over C:
// Must match declaration order (preserves unwrap order)
// No array initializers (conflicts with lambda syntax)
struct A { int x, y; };
struct B { struct A a; };
struct A a = {.y = 1, .x = 2}; // valid C, invalid C++
int arr[3] = {[1] = 5}; // valid C, invalid C++
struct B b = {.a.x = 0}; // valid C, invalid C++
struct A a = {.x = 1, 2}; // valid C, invalid C++P0428R2: Templating Lambdas!
- Allow SFINAE/enable_if, plus good for Concepts.
// Syntax: Add '<..>' for template, no template keyword:
//[capture-list]<template-list>(param-list){stmt-list}
auto ident = [=]<typename T>(T& t) { return t; };P0428R2: Templating Lambdas!
- Allow SFINAE/enable_if, plus good for Concepts.
// Syntax: Add '<..>' for template, no template keyword:
//[capture-list]<template-list>(param-list){stmt-list}
auto ident = [=]<typename T>(T& t) { return t; };P0734R0: Concepts->WD
- Concepts are now in C++2a! Syntax altered during the meeting.
// 'bool' removed from definition:
template<typename T>
concept EqualityComparable = requires(T a, T b) {
{a ==b }->bool;
};
// 'terse' syntax killed.
void f(EqualityComparable e); // Not legal
template<EqualityComparable T>
void f (T e); // Still allowed
template<typename T> requires EqualityComparable<T>
void f( T e); // Alternate definition syntax.P0463R1: endian, Just endian
- Ability to tell endianness (library):
// type_traits header:
enum class endian
{
little = ...,
big = ...,
native = ...
};P0674R1: array make_shared
- Let make_shared/allocate_shared work with Arrays:
// 23.11.2.2.6, shared_ptr creation
template<class T, class... Args>
shared_ptr<T> make_shared(Args&&... args); // T is not array
template<class T, class A, class... Args>
shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not array
template<class T> shared_ptr<T> make_shared(size_t N); // T is U[]
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]
template<class T> shared_ptr<T> make_shared(); // T is U[N]
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a); // T is U[N]
template<class T>
shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[]
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, size_t N,
const remove_extent_t<T>& u); // T is U[]
template<class T> shared_ptr<T>
make_shared(const remove_extent_t<T>& u); // T is U[N]
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a,
const remove_extent_t<T>& u); // T is U[N]Others:
- Modules TS approved (To PDTS).
- A few Coroutines TS changes.
- A bunch of Ranges TS fixes.
- A bunch of Networking TS fixes.
- 1 Parallelism TS V2 fix.
Fin
N4681: Modules -> PDTS!
- Modules TS approved!
deck
By Erich Keane
deck
- 716