El otro día hubo una reunión del comité internacional de normalización C ++ en Colonia. La última vez, la congelación de características se adoptó en C ++ 20, por lo que el comité solo debe discutir las correcciones de las cosas ya aceptadas y agregar nuevos elementos ya en C ++ 23 ...
... pero no fue así!

¿Qué hicieron con std :: flat_map; ¿Se mantendrán las palabras clave de miedo co_return, co_await y co_yield; ¿lograste terminar std :: format; ¿Qué tipo de contratos habrá en C ++ 20? Todo esto te espera bajo el corte.
Grupo de trabajo de evolución
Lunes
El día estaba ocupado: decidimos cambiar el nombre de todos los conceptos en snake_case en lugar de CamelCase. Además, la propuesta
P1607 , que cambia la sintaxis y el comportamiento de los contratos a una más comprensible (pero también requiere macros), fue
ampliamente expresada .
Martes
Corutinas discutidas. Rechazamos todo, incluida nuestra propuesta de
eliminar co_ de las palabras clave para la rutina . Por desgracia
Miercoles
De repente, nos dimos cuenta de que nadie aprobó la propuesta
P1607 aprobada el lunes en la práctica, se discutió durante unos 30 minutos, mientras que la decisión existente sobre los contratos se perfeccionó durante muchos años.
Después de una larga discusión, decidieron que, en principio, los contratos no están listos para C ++ 20. Y los eliminó del estándar.
Jueves viernes
Discutimos cosas para C ++ 23. Las fuerzas principales se centraron en nuevos mecanismos en el manejo de errores. Hubo
ideas generales sobre el tema y propuestas específicas para un
nuevo especificador de excepción de lanzamientos .
Grupo de trabajo de la biblioteca
El comité tiene un subgrupo LWG. Cualquier documento que agregue funcionalidad a la biblioteca estándar debe someterse a una revisión en este subgrupo.
El rendimiento promedio de LWG es de ~ 30 documentos por semana. En Colonia, fue necesario considerar más de 50 documentos, entre los cuales aproximadamente la mitad eran tamaños extremadamente impresionantes, por ejemplo:
*
std :: flat_map*
std :: jthread*
operador <=> para la biblioteca estándar*
Nuevas primitivas de sincronización+ El papel vino de EWG para renombrar conceptos en snake_case.
¿Cuál de los aprobados anteriormente logró arrastrar a C ++ 20?
- en constexpr ahora no es necesario inicializar a cero cada variable . Abajo con int i {}; larga vida int i;.
- Requiere ahora se puede utilizar para constructores y destructores. En consecuencia, ahora en la clase puede haber varios destructores:
#include <type_traits>
template<typename T>
struct Optional {
// ...
~Optional() requires(std::is_trivially_destructible_v<T>) = default;
~Optional() requires(!std::is_trivially_destructible_v<T>) {
if (inited_) reinterpret_cast<T&>(data_).~T();
}
private:
bool inited_{false};
std::aligned_storage_t<sizeof(T), alignof(T)> data_;
};
- [[nodiscard]] . , :
template <class F>
[[nodiscard("Without storing the result the code executes synchronously")]] future async(F&& );
auto test() {
// ...
// warning: Without storing the result the code executes synchronously
async([huge_data](){
std::cerr << huge_data;
});
}
- using enum:
enum class rgba_channel { kRed, kGreen, kBlue, kAlpha};
std::string_view to_string(rgba_channel channel) {
using enum rgba_channel;
switch (channel) {
case kRed: return "red";
case kGreen: return "green";
case kBlue: return "blue";
case kAlpha: return "alpha";
}
}
- Deduction guides :
template <typename T>
struct S {
T x;
T y;
};
S t{'4', '2'}; // Deduces `S<char>`
- __asm constexpr ( !)
- . :
void f(int(&)[]); // p.s.:
int arr[1];
f(arr); // OK
- C++20
- constinit :
int count_invocations() {
// ,
// `counter` .
//
// - ,
//
// `counter` .
static constinit std::atomic<int> counter{0};
return ++counter;
}
- .
- volatile deprecated. .
- [[nodiscard]] , :
struct [[nodiscard]] my_scopeguard { /* ... */ };
struct my_unique {
[[nodiscard]] my_unique(int fd) { /* ... */ } //
/* ... */
};
void sample() {
my_scopeguard(); // warning
void(my_scopeguard()); // cast void, warning
my_unique(42); // warning
}
- Class Template Argument Deduction
- std::vector placement new constexpr
- <bit> . , / /, — .
- <format> , chrono locale float:
constexpr auto birthday = 28d/April/1989;
string s = format("At {0:%d} of {0:%B}, {0:%Y} someone was born", birthday);
assert(s == "At 28 of April, 1989 someone was born");
- constexpr bind, invoke, reference_wrapper
- <numbers>
- wait notify. conditional_variable:
#include <atomic>
enum class States {
kInitial, kProcessing, kPosting,
};
// ! !
std::atomic<States> state{States::kInitial};
void state_machine_do_posting() {
for (;;) {
States expected_state = States::kProcessing;
// kProcessing
state.wait(expected_state);
if (!state.compare_exchange_strong(expected_state, States::kPosting)) {
continue;
}
// do something
}
}
- snake_case
- operator != operator ==. , operator <=>
- std::*stringstream std::basic_stringbuf :
std::string to_string(const MyType& v) {
std::string buf;
constexpr std::size_t kMaxSize = 32;
buf.reserve(kMaxSize);
// C++20 , C++20 —
std::ostringstream oss{std::move(buf)};
oss << "MyType{" << v << '}';
// C++20 , C++20 —
return std::move(oss).str();
}
- std::jthread:
#include <thread>
void sample() {
bool ready = false;
std::mutex ready_mutex;
std::condition_variable_any ready_cv; // `_any`!
std::jthread t([&ready, &ready_mutex, &ready_cv] (std::stop_token st) {
while (!st.stop_requested()) {
/* ... */
{
std::unique_lock lock{ready_mutex};
// ready == true, stop_token.request_stop(),
// jthread.request_stop().
ready_cv.wait_until(lock, [&ready] { return ready; }, st);
}
/* ... */
}
});
/* ... */
// `t` request_stop() .
}
- type_traits , .
antoshkka C++14 CppCon. , . … , .
, . , type_traits :
Over dinner at CppCon, Marshall Clow and I discussed a bit of code that relied on two types being layout-compatible. As it happened, the types weren’t layout-compatible after all. I opined that there should be a way to statically assert layout-compatibility, so that the error would be caught at compile time, rather than dinner time. Marshall replied, “Write a proposal.” This is that proposal.
- std::source_location, , .
- unordered . .
, std::stacktrace, std::flat_map, std::flat_set C++20 :(
++23
, Boost.Process , /, , , 2d , , JIT C++ .
.
std::filesystem::path_view. path_view , .
21
, , , , , , . , , std::format Inf/NaN; jthread;
pair, tuple, string, array.
SG1 Concurrency concurrent_unordered_map. visit value , :
concurrent_unordered_map<int, std::string> conc_map;
conc_map.visit(42, [](std::string& value) { // , ....
// OK. OK value.
std::cerr << value;
// OK. OK value.
value += "Hello";
});
.
, :
concurrent_unordered_map<int, std::atomic<int>> conc_map;
conc_map.visit(42, [](std::atomic<int>& value) { // , ....
// OK
++ value;
});
SG6 Numerics — Numerics TS , wide_integer .
C++ Piter, .
21 ISO 9 (
, ). C++20 C++23.