【C++学習|豆知識】C++20の新定番!std::map::containsでコードをより直感的に

なぜstd::map::containsを使うのか?

C++のプログラミングにおいて、std::mapなどの連想コンテナから特定のキーが存在するかを確認する処理は非常に頻繁に行われます。これまではstd::map::findメソッドを使い、戻り値がend()と等しいかどうかを比較するのが一般的でした。しかし、この方法はコードが冗長になりがちで、意図が直感的に伝わりにくいという課題がありました。C++20で導入されたstd::map::containsは、この「キーの存在確認」という目的を一行で、かつ明示的に表現できるため、コードの可読性を劇的に向上させます。

基礎知識:std::mapと検索の仕組み

std::mapは「キー」と「値」のペアを保持する連想コンテナで、内部的には二分探索木(主に赤黒木)として実装されています。そのため、要素の検索は対数時間(O(log n))で行われます。
従来使われてきたstd::map::findは、見つかった場合はその要素を指すイテレータを返し、見つからなかった場合はコンテナの終端を指すiterator(std::map::end)を返します。この「イテレータを介した比較」は、単に「存在するかどうかだけを知りたい」という場合には少し情報過多で、記述が長くなる要因となっていました。

実装と解決策

std::map::containsは、キーが存在する場合は「true」、存在しない場合は「false」を返します。findメソッドのように、返されたイテレータをend()と比較するステップが不要になります。これにより、条件分岐(if文)が非常にスッキリし、バグの混入リスクも低減します。

サンプルプログラム

以下のコードをコピーして、C++20対応のコンパイラで実行してみてください。

include
include

include

int main() {
// マップの初期化
std::map inventory = {
{“apple”, 10},
{“banana”, 5}
};

// 検索したいキー
std::string item = “apple”;

// C++20以前の書き方(冗長)
if (inventory.find(item) != inventory.end()) {
std::cout << "findメソッド: " << item << " は存在します。" << std::endl; } // C++20からの書き方(直感的で読みやすい) if (inventory.contains(item)) { std::cout << "containsメソッド: " << item << " は存在します。" << std::endl; } else { std::cout << item << " は見つかりませんでした。" << std::endl; } return 0; }

応用・注意点

注意点1:C++20以降の環境が必要
std::map::containsはC++20から追加された機能です。コンパイル時には必ず「-std=c++20」フラグを指定してください。古いプロジェクトでC++17以前の環境を使用している場合は、残念ながら利用できません。

注意点2:findとの使い分け
containsは「存在確認」には最適ですが、もし検索した値を使ってその後の処理(要素の書き換えや参照など)を行いたい場合は、findを使用したほうが効率的です。containsで見つけた後にfindを呼ぶと、二重に検索処理が走ってしまうため、必要なデータにアクセスしたい場合は最初からfindでイテレータを取得するようにしましょう。

コードの意図を明確にする小さな工夫が、将来の自分やチームメンバーへの大きな贈り物になります。ぜひ積極的に活用してみてください。

コメント

タイトルとURLをコピーしました