#include <bits/stdc++.h> と using namespace std; は何をしているのか
以下は典型的C++のHello World!コードです。
#include <bits/stdc++.h>
using namespace std;
int main() {
cout << "Hello World!" << endl;
}
さて、今回話すのはこのコードの頭2行です。これらの部分は、よく入門書などで"おまじない"として紹介され、後回しにされるケースがほとんどです。
このコードを実際の運用に適切なコードへ書き換えると、
#include <iostream>
int main() {
std::cout << "Hello World!" << std::endl;
}
となります。何故このような違いがでるのか、何故これらが用いられるか、以下に解説していきます。
#include <bits/stdc++.h> は何か
何をしているか
C++における全ての標準機能(標準ヘッダ)を取り込んでいます。
C++には、cout, cin等入出力機能を提供する<iostream>や可変長配列vectorクラスを提供する<vector>等多くの標準ライブラリがあります。
これらは必要に応じて
#include <iostream>
#include <vector>
などで取り込まれますが、
#include <bits/stdc++.h>
の使用によってこれらを一度に取り込むことができます。
何故使うのか
C++の標準ライブラリは各機能毎にある程度分割されたヘッダとして提供されています。そのため、必要に応じた#includeが行われますが、初心者の学習において"この機能はどのヘッダで提供されているか"というのはそこまで重要でなくノイズです。また、早さが肝となる競技プログラミングにおいても、同様にノイズであるためこれが用いられます。
何故適切でないか
前項にあげた2つのケースでは、#include <bits/stdc++.h>は推奨されるでしょう。では何故、これらが業務等に相応しくないのでしょうか。
それは主に、このヘッダが環境依存であることです。
C++はコンパイル言語であり、C++で書かれたソースコードはコンパイラが機械に理解できるように翻訳することで初めて動作します。
C++のコンパイラは複数あります。主なものでは、
- GCC
- Clang
- MSVC
というものがありますが、bits/stdc++.hはGCCによって提供されています。ClangやMSVCでは提供されておらず、GCCという環境要素に依存しています。
他には
- 未使用定数の定義
- 解析/補完等への影響
などがあげられます。
using namespace std; は何か
何をしているか
名前空間の省略、この場合、標準ライブラリ(std)の名前空間を省略します。
名前空間は名前の付いた空間に関数やクラスを入れることで、これらを区別/構造化し、保守性/可読性を向上させます。
namespace hoge {
void do_something();
}
int main() {
hoge::do_something();
}
名前空間はこのように使用され、C++で提供される標準ライブラリはstd名前空間内で定義されています。
さて、この名前空間ですが、省略できます。
// さっきと同じコード
using namespace hoge;
int main() {
do_something();
}
または、
// ry
using hoge::do_something;
int main() {
do_something();
}
このように、using naemspaceで名前空間に含まれるすべて、usingで特定の関数を対象に名前空間の省略が行ます。
何故使うのか
std名前空間の省略です。学習や競技プログラミングにおいて、いちいちstd::と入力していていいことはないので、そのような場面で用いられます。
何故適切でないか
名称の衝突です。標準ライブラリは膨大で、さまざまな名称が用いられます。この際、標準ライブラリの名称と外部ライブラリの名称が衝突することで、エラーの発生につながります。
使用しない、またはusingで対象を絞って省略するのが望ましいでしょう。