先日 AtCoder にて新ジャッジのテストコンテストが公開されました.
C++ (GCC/Clang) のインストールスクリプトを (成り行きで) 担当しましたので現時点での更新内容等を簡単に述べます.
注意
この記事の内容について
この記事に記載されている内容はすべて暫定かつ非公式のものであり, 新ジャッジの正式リリースまでに変更される可能性があります. ご承知おきください.
現在も協議中ですので, AtCoder 公式の Discord サーバー よりぜひご参加ください: AtCoder 言語アップデート 2024-2025
実行時間とメモリ使用量について (GCC)
現在非常に単純なソースコードでも 実行時間: / 消費メモリ: 程度を要してしまうという問題が確認されています.
これは恐らく不要なライブラリがリンクされてしまっていることによるものであり, 現在修正作業中です.
環境
GCC 15.1.0
主要なコンパイルフラグ
-std=gnu++23
-DONLINE_JUDGE
, -DATCODER
-Wall
, -Wextra
-O2
, -march=native
, -flto=auto
-lstdc++exp
, -fopenmp
-fmodules
Clang 20.1.3
主要なコンパイルフラグ
-std=gnu++23
, -stdlib=libc++
-fuse-ld=lld
, -rtlib=compiler-rt
, -unwindlib=libunwind
-DONLINE_JUDGE
, -DATCODER
-Wall
, -Wextra
-O2
, -march=native
, -flto=auto
-fexperimental-library
, -fopenmp
新機能 (C++20, C++23)
以下には 競プロ (コンテスト参加, ライブラリ整備) に役立ちそうなものを抜粋します.
詳細なリストについては 各 処理系/ライブラリ のドキュメント等をご参照ください.
各項の見出しは関連文献へのリンクになっています.
標準ライブラリ
GCC は libstdc++, Clang は libc++ をリンクします.
std::ranges
現在利用可能なものに加えて, 様々な range adaptor 等が利用できます.
Ranges to container [P1206R7] (libstdc++, libc++)
User-defined range adaptors [P2387R3] (libstdc++, libc++)
Folding [P2322R6] (libstdc++)
std::ranges::fold_left
std::ranges::fold_left_first
std::ranges::fold_right
std::ranges::fold_right_last
std::ranges::fold_left_with_iter
std::ranges::fold_left_first_with_iter
Views
std::ranges::join_with_view
[P2441R2] (libstdc++)std::ranges::enumerate_view
[P2164R9] (libstdc++)std::ranges::repeat_view
[P2474R2] (libstdc++, libc++)std::ranges::cartesian_product_view
[P2374R4, P2540R1] (libstdc++)std::ranges::as_const_view
[P2278R4] (libstdc++)std::ranges::as_rvalue_view
[P2446R2] (libstdc++, libc++)std::ranges::stride_view
[P1899R3] (libstdc++)std::ranges::chunk_by_view
[P2443R1] (libstdc++, libc++)std::ranges::chunck_view
,std::ranges::slide_view
[P2442R1] (libstdc++)
Zip [P2321R2] (libstdc++)
std::ranges::zip_view
std::ranges::zip_transform_view
std::ranges::adjacent_view
std::ranges::adjacent_transform_view
find_last
[P1223R5] (libstdc++, libc++)
contains
[P2302R4] (libstdc++, libc++)
starts_with
, ends_with
[P1659R3] (libc++)
std::flat_map [P0429R9] (libstdc++, libc++); std::flat_set [P1222R4] (libstdc++)
線形コンテナ (e.g., std::vector
, std::deque
) 上に二分探索木を構築するデータ構造です.
挿入/削除 のパフォーマンスを犠牲にしている分, 検索が軽いです.
<stdfloat>
[P1467R9] (libstdc++)
拡張固定幅浮動小数点数型です.
<cstdint>
で定義される固定幅整数型とは異なり, 拡張浮動小数点数型のエイリアスとなるため, int
, double
, long double
の完全互換品とはなりません.
std::float128_t
128 bits の 4 倍精度浮動小数点数型です.
literal suffix は f128
, F128
です.
<generator>
[P2502R2, P2787R0] (libstdc++)
コルーチンが手軽に使えます.
libc++ でも, 省機能の generator を自前実装することはできます.
<format>
[P0645R10], <print>
[P2093R14] (libstdc++, libc++)
std::format
, std::print
, std::println
などが使えます.
([P0645R10:Performance] や [P2093R14:Performance] に拠れば printf
よりも速いらしいです. )
Formatting Ranges [P2286R8] (libstdc++, libc++)
std::format
がデフォルトで ranges のフォーマットに対応します. (ただし, GCC 15.1.0 時点での libstdc++ では experimental support だそうです. おそらく 15.2 で正式にサポートされます.)
これは std::print
, std::println
にも利用されます.
なお競プロ用途では頻繁に用いるコンテナに対する特殊化を予め用意しておくとよいでしょう.
<stacktrace>
[P0881R7, P2301R1] (libstdc++)
std::stacktrace
などが使えます.
std::mdspan
(libc++)
std::span
の多次元版です.
std::experimental::simd
(libstdc++, libc++)
libstdc++ と lib++ とで提供されている機能に差があるので注意してください. (前者の方が多少実装が進んでいます. )
詳しくは各ライブラリのドキュメントやソース等をご参照ください.
Iterators pair constructors for stack and queue [P1425R4] (libstdc++, libc++)
std::stack
, std::queue
のコンストラクタが引数として input iterator の組を受け取れます.
Calendars and Time Zones [P0355R7] (libstdc++)
<chrono>
でカレンダーやタイムゾーンが扱えます.
std::basic_string::contains, std::basic_string_view::contains [P1679R3] (libstdc++, libc++)
std::basic_string
, std::basic_string_view
の連続部分文字列検索です.
Monadic operations for std::optional [P0798R8] (libstdc++, libc++)
std::optional::and_then
, std::optional::transform
, std::optional::or_else
等がサポートされます.
Function to mark unreachable code [P0627R6] (libstdc++, libc++)
を事前条件とする関数 std::unreachable
が利用できます.
これは, 最適化に利用される可能性があります.
Default Arguments for pair
's Forwarding Constructor [P1951R1] (libstdc++, libc++)
(説明略)
言語機能
Modules [P1103R3] (GCC: partial, Clang: partial)
従来のヘッダファイルの一部のユースケースの代替として利用できる, 翻訳単位間で宣言と定義を共有するための言語機能です.
競プロで主に役立つのは専ら標準ライブラリモジュールでしょう. 詳しくは「モジュール」の項をご参照ください.
Deducing this
[P0847R7] (GCC, Clang)
explicit object parameter (明示的オブジェクトパラメータ) が宣言可能になり, 推論も働きます.
static operator(), operator[] [P1169R4, P2589R1] (GCC, Clang)
this
ポインタを利用しない operator()
, operator[]
が static
として定義できます. これはラムダ式にも適用されます.
Relaxing some constexpr restrictions [P2448R2] (GCC, Clang)
実際に定数式文脈で呼び出さない限り, 定数式実行できない constexpr
関数の存在が許可されるようになります.
A trait for implicit lifetime types [P2647R1] (GCC, Clang)
constexpr
関数内の static constexpr
変数が許可されます.
consteval
needs to propagate up [P2564R3] (GCC, Clang)
consteval
関数呼び出しを含む constexpr
関数が条件付きで暗黙に consteval
関数になります.
Narrowing contextual conversions to bool [P1401R5] (GCC, Clang)
static_assert
, if constexpr
における bool
への暗黙の縮小型変換が許可されます.
Compatibility between tuple, pair and tuple-like objects [P2165R4] (GCC, Clang)
std::tuple<2>
, std::pair
, std::array<2>
などの相互互換性が向上します.
ただし, C++20 では許可されていた以下のような構文は ill-formed になります:
auto x = true ? std::pair{ 0, 1 } : std::tuple{ 0, 1 };
Extend init-statement to allow alias-declaration [P2360R0] (GCC, Clang)
for
文の初期化子にエイリアス宣言 (using
) を含められます.
Multidimensional operator[] [P2128R6] (GCC, Clang)
operator[]
が引数を複数取れます.
Class template argument deduction from inherited constructors [P2582R1] (GCC)
継承コンストラクタや派生クラスの推論補助から基底クラスのテンプレート引数を推論できます.
Literal Suffix for (signed) size_t
[P0330R8] (GCC, Clang)
(符号付き) std::size_t
型のリテラルが 12345z
や 12345Z
と書けます.
u
, U
との併用も可能です.
constexpr std::bitset [P2417R2] (GCC, Clang)
std::bitset
が定数式内で利用できます.
if consteval [P1938R3] (GCC, Clang)
関数の呼び出しがコンパイル時かどうかを判定できます.
Portable assumptions [P1774R8] (GCC, Clang)
実行時に満たされているはずの仮定を明示し, (最適化に利用できる情報として) コンパイラに伝えることができます.
Simpler implicit move [P2266R3] (GCC, Clang)
暗黙 move の仕様が簡略化され, ローカル変数あるいはローカル rvalue reference の, 返却値が参照の場合の暗黙ムーブが認められます.
C++20 と比較して, 一部の場合で返却値の型推論の結果が変わる場合があります.
モジュール
Standard Library Modules (std, std.compat) [P2465R3] (GCC, Clang)
import std;
や import std.compat;
と記述することで標準ライブラリをモジュールとして扱えます. (後者は, std
モジュールに加えてグローバル名前空間に C 互換ライブラリも導入します. )
コンパイル時間も (#include <bits/stdc++.h>
に比べて) かなり短縮されるはずです.
注意点
Modules は GCC, Clang 共に partial support です. 未実装の部分がいくつか存在するため注意してください.
その多くは通常の利用に際しては影響のないものと思われますが, 次に示す事項には留意しておくとよいでしょう.
import
の後に #include
を置かない
import
に続く #include
は GCC, Clang ともに「実装されていない」「サポートされていない」と明言されています. #include
と import
とを併用する場合は import
を最後に置くようにしましょう.
intrinsics と併用しない (GCC)
これはおそらく明文化されていないのですが, Standard Library Modules と intrinsic ヘッダ (e.g., emmintrin.h
, immintrin.h
) の #include
とを併用すると conflicting language linkage for imported declaration
というコンパイルエラーが発生する場合があるようです. 15.1.0 では修正されていません.
その他
bits/stdc++.h
support for Clang
Clang
で #include <bits/stdc++.h>
が利用できます.
(インストールスクリプト内で愚直に生成しています. GCC のそれと等価であることは保証されません.)
sudo mkdir -p "${install-prefix}/include/bits"
find "${install-prefix}/include/c++/v1" -maxdepth 1 -type f ! -iname '__**' ! -iname '**.**' -exec echo '#include <{}>' \; |
sudo tee "${install-prefix}/include/bits/stdc++.h"
その他のライブラリ
先にも述べましたが, 以下はすべて協議段階のものです.
現時点では提案があったものすべてのサポートを準備していますが, 反対意見や非肯定的な見解が相次げば提案が取り下げられる場合もあります. ぜひ策定にご協力ください.
Official
AtCoder Library (AC-Library): 1.6
ここに詳細は述べませんが , ACL や C++ のバージョンに上がったことで . 現行のジャッジの C++23 でもできるみたいです (コメントでご指摘をいただきました.ありがとうございます.).atcoder::segtree
のテンプレートパラメータにラムダ式を渡せるようになっていたりします
Utility
Range-v3: 0.12.0
現在の <ranges>
の前身となっているライブラリです.
各処理系の実装が追いついていない view 等が使えたりします. (ほとんどのものはいずれ C++ 標準で使えるようになるはずです.)
unordered_dense: 4.5.0
Robin Hood hashing と Backward shift deletion による set, map です.
Advanced STL-like
Abseil: 20250127.1
C++ Standard Library の拡張として Google が使用していたライブラリ群を外部向けに公開したものです.
Boost C++ Library (Boost): 1.88.0
言わずと知れた Boost です.
Mathematical
Eigen: 3.4.0
線形代数演算の老舗ライブラリです.
GNU Multi-Precision Library (GMP): 6.3.0
GNU 製の算術ライブラリです.
多倍長整数演算や任意精度演算のサポートが含まれます.
Machine Learning
LibTorch: 2.7.0
PyTorch の C++ API です.
LightGBM: 4.6.0
機械学習用の分散型勾配ブースティングフレームワークです.
Solver
OR-Tools: 9.12
組合せ最適化問題の解決を得意とするソフトウェアです.
利用可能なソルバの一覧を次に示します:
Z3 (The Z3 Thorem Prover): 4.15
Satisfiability modulo theories (SMT) ソルバーです.