Erich Keane erich.keane@verizon.net
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}}; explicit struct E {
Color c;
int r;
};
E e; // error, doesn't init everything.
E e1{Color::red}; // Same.
//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:
//...
}
}[](auto const& s) => s == 2;
// Equivalent to:
[](auto const& s) noexcept(s == 2) -> decltype((s==2)) {
return s == 2;
}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.// 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;
};// 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.
};// 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.struct S {
unsigned A : 5;
unsigned B : 4;
unsigned C : 3;
};
//bit_sizeof(S::B) == 4
//bit_offsetof(S, C) == 9
// 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... */
}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
};
void Type::foo() {
[=] () {}; // captures 'this' by pointer
[=, *this] () {}; // captures 'this' by copy.
[=,this]() {} // same as 1st, but now explicit.
}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++// Syntax: Add '<..>' for template, no template keyword:
//[capture-list]<template-list>(param-list){stmt-list}
auto ident = [=]<typename T>(T& t) { return t; };// Syntax: Add '<..>' for template, no template keyword:
//[capture-list]<template-list>(param-list){stmt-list}
auto ident = [=]<typename T>(T& t) { return t; };// '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.// type_traits header:
enum class endian
{
little = ...,
big = ...,
native = ...
};// 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]