web-dev-qa-db-ja.com

#include <algorithm>を使用しなくても、std :: maxとstd :: minを使用できるのはなぜですか?

#include <iostream>

int main()
{
   int value1 = 1, value2 = 10;
   std::cout << "Min = " << std::min(value1,value2) <<std::endl;
   std::cout << "Max = " << std::max(value1,value2)<< std::endl;              
} 

私の知る限り、min関数とmax関数は<algorithm>で定義されています。

プリプロセッサに<algorithm>を含めるように指示しなかった場合、コードが引き続き機能するのはなぜですか?

16
Anthony

ほとんどの場合、iostream内の何かに、std::minstd::maxを定義する他のヘッダーが直接的または間接的に含まれています。 (おそらくalgorithm自体が含まれています。おそらく、C++標準ライブラリを実装するために使用されるいくつかの内部ヘッダーです。)

この動作に依存しないでください。 std :: minとstd :: maxが必要な場合は、algorithmを含めます。

モジュールが他のモジュールをインポートでき、インポートから何もエクスポートすることを強制されないモジュールシステム(Racketのモジュールシステムなど)を使用する言語に慣れている場合、この動作は混乱を招く可能性があります。

ただし、#includeがテキスト置換を行っていることを思い出してください。 #include行が処理されると、.cppファイルから削除され、それが指していたファイルの内容に置き換えられます。

ほとんどのコンパイラには、プリプロセッサの実行の出力をダンプするオプションがあるため、何が何を含んでいるかを追跡できます。 kmortの回答に対するコメントで、Visual StudioExpressを使用しているとおっしゃいました。 Visual C++コンパイラを使用して ファイルをファイルに前処理する へのコマンドラインはcl /P foo.cppです。この出力を使用すると、std::maxの定義が実装固有のヘッダーxutilityからのものであることがわかります。 (テキスト「std:max」内にキャレットを配置し、Visual StudioでF12キーを押すと、さらに高速になります。:-])

kmortは、 /showIncludes コンパイラスイッチについても言及しました。これを使用して、インクルードチェーンを簡単に追跡できます。これが私の実行からの減少した出力です。

Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\iostream
Note: including file:  C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\istream
Note: including file:   C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\ostream
Note: including file:    C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\ios
Note: including file:     C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocnum
Note: including file:      C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\streambuf
Note: including file:       C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xiosbase
Note: including file:        C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocale
Note: including file:         C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\stdexcept
Note: including file:          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xstring
Note: including file:           C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0
Note: including file:            C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xutility
21
chwarr

どのコンパイラを使用していますか?

私は以前、libcまたはlibstdc ++で定義されている一般的な項目に対していくらか「寛容」であるコンパイラを見てきました。それはあなたのために参照を引き出します。つまり、リンクするように指示したり、ヘッダーを含めたりする必要はありません。それはうまくいきます。 min()max()については予想していなかったでしょうが、それほど驚くことではありません。

これは、含める必要のあるヘッダーを含む他のヘッダーによっても発生する可能性がありますが、これに依存しないでください。そして、私はそれがこの場合に起こったとは思わない。

2
kmort