/changelogs/cpp/cpp20-to-cpp23
C++20 to C++23: what changed in the language, tested with g++ -std=c++23
- tool
- C++
- versions
- 20 → 23
C++23 adds a handful of language features to C++20: a multidimensional operator[], static operator(), if consteval, auto(x), the #elifdef and #elifndef directives and "deducing this". GCC tracks them on its C++ status page and describes the C++23 support as experimental; the features arrive over several releases, so a feature that works in one GCC may be missing in an older one. Enable the standard with -std=c++23 (see __cplusplus values for how to detect it).
Language features
| Feature | Example | Under -std=c++20 |
|---|---|---|
| Multidimensional subscript | int operator[](int r, int c) const | Error: operator[] must have exactly one argument |
| static operator() | static int operator()(int a, int b) | Warning that it needs -std=c++23 |
| if consteval | if consteval { ... } else { ... } | Warning that it needs -std=c++23 |
| auto(x) | auto y = auto(x); | Warning that it needs -std=c++23 |
| #elifdef, #elifndef | #elifdef NAME | Preprocessor shortcut for #elif defined(NAME) |
| Deducing this | int get(this const S& self) | Needs a newer GCC than 13.3 even with -std=c++23 |
- Multidimensional subscript.
grid[1, 0]now callsoperator[](int, int). In C++20 the comma in a subscript is deprecated, and GCC warns with-Wcomma-subscript. static operator(). A function object with no state can have a static call operator, which avoids passing an unusedthis.if consteval. Chooses a branch depending on whether the function is being evaluated at compile time. At run time theelsebranch runs.auto(x). Makes a copy ofxwith decayed type, as a prvalue.- Deducing this. An explicit object parameter, written
this const S& self, replaces overloads for const and non-const objects.
Test it with g++
cat > t23.cpp <<'EOF'
struct Grid {
int d[2][2] = {{1, 2}, {3, 4}};
int operator[](int r, int c) const { return d[r][c]; }
};
struct Add { static int operator()(int a, int b) { return a + b; } };
constexpr int f() { if consteval { return 1; } else { return 2; } }
#ifdef FOO
#elifdef __cplusplus
#define KIND "elifdef"
#endif
int main() {
Grid g; int x = 5;
auto y = auto(x);
return g[1, 0] + Add{}(2, 3) + f() + y + (KIND[0] == 'e');
}
EOF
g++ -std=c++23 -Wall t23.cpp -o t23 && echo "c++23 builds"
g++ -std=c++20 -Wall t23.cpp -o t20 2>&1 | grep "error:" | head -1Output
c++23 builds t23.cpp:3:9: error: ‘int Grid::operator[](int, int) const’ must have exactly one argument
The first command compiles the file as C++23. The second compiles it as C++20 and prints the first error: the two-argument operator[] is rejected.
Upgrade checklist
- Set
-std=c++23(orCMAKE_CXX_STANDARD 23) and read the new warnings. - Search for
[a, b]subscripts, which change meaning. - Check each new feature against your compiler in the GCC status table before using it in shared code.
- Library features (such as
std::expected) are tracked separately; test them with the feature macros from<version>. - Compile errors about functions that no longer match are described in no matching function for call.
FAQ
How do I enable C++23 in g++?
Pass -std=c++23, or -std=gnu++23 to keep GNU extensions. The GCC status page says C++23 features are available since GCC 11. New features arrive release by release, so check the table for your version.
Is C++23 fully supported in GCC?
GCC describes its C++23 support as experimental and adds features over several releases. In a test with GCC 13.3, most language features below compiled, but deducing this was rejected. Check the GCC C++ status page for the release you use.
What does the code a[i, j] mean in C++23?
It calls a two-argument operator[] on the object. Before C++23 the comma was the comma operator and only the last value was used as the index. GCC warns about the old meaning under C++20 with -Wcomma-subscript.