Suatu hari ada pertemuan komite standardisasi internasional C ++ di Cologne. Terakhir kali, pembekuan fitur diadopsi dalam C ++ 20, sehingga panitia hanya harus membahas koreksi dari hal-hal yang sudah diterima, dan menambahkan item baru sudah di C ++ 23 ...
... tapi ternyata tidak begitu!

Apa yang mereka lakukan dengan std :: flat_map; Apakah kata kunci menakutkan co_return, co_await dan co_yield tetap; apakah Anda berhasil menyelesaikan std :: format; Apa jenis kontrak dalam C ++ 20? Semua ini menanti Anda di bawah luka.
Kelompok Kerja Evolusi
Senin
Hari itu sibuk - kami memutuskan untuk mengganti nama semua konsep di snake_case alih-alih CamelCase. Selain itu, proposal
P1607 , yang mengubah sintaksis dan perilaku kontrak menjadi lebih mudah dimengerti (tetapi juga membutuhkan makro),
disuarakan secara luas .
Selasa
Korut dibahas. Menolak segalanya, termasuk proposal kami untuk
menghapus co_ dari kata kunci untuk coroutine . Sayang
Rabu
Tiba-tiba kami menyadari bahwa tidak ada yang menyetujui proposal
P1607 yang disetujui pada hari Senin dalam praktik, itu dibahas selama sekitar 30 menit, sementara keputusan yang ada pada kontrak itu diasah selama bertahun-tahun.
Setelah diskusi panjang, mereka memutuskan bahwa kontrak pada prinsipnya tidak siap untuk C ++ 20. Dan menghapusnya dari standar.
Kamis jumat
Hal-hal yang didiskusikan untuk C ++ 23. Kekuatan utama difokuskan pada mekanisme baru dalam penanganan kesalahan. Ada
pemikiran umum tentang topik dan proposal spesifik untuk
specifier pengecualian lemparan baru .
Kelompok kerja perpustakaan
Panitia memiliki subkelompok LWG. Setiap dokumen yang menambah fungsionalitas ke pustaka standar harus menjalani peninjauan di subkelompok ini.
Throughput rata-rata LWG adalah ~ 30 dokumen per minggu. Di Cologne, perlu mempertimbangkan lebih dari 50 dokumen, di antaranya sekitar setengahnya berukuran sangat mengesankan, misalnya:
*
std :: flat_map*
std :: jthread*
operator <=> untuk perpustakaan standar*
Primitif sinkronisasi baru+ Kertas berasal dari EWG untuk mengubah nama konsep di snake_case.
Manakah dari yang sebelumnya disetujui berhasil menyeret ke C ++ 20
- di constexpr, sekarang tidak perlu untuk menginisialisasi ulang setiap variabel . Turun dengan int i {}; long live int i;.
- membutuhkan sekarang dapat digunakan untuk konstruktor dan destruktor. Dengan demikian, sekarang di kelas ada beberapa destruktor:
#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.