含めるヘッダーファイルを決定する方法


13

以下の(非常に単純な)コードがあるとします。

#include <iostream>
int main() {
    std::cout << std::stoi("12");
}

これは、g ++とclangの両方で正常にコンパイルされます。ただし、次のエラーによりMSVCでコンパイルできません。

エラーC2039: 'stoi':は 'std'のメンバーではありません

エラーC3861: 'stoi':識別子が見つかりません

私はそれstd::stoi<string>ヘッダーの一部であることを知っています。おそらく前者の2つのコンパイラーはその一部としてインクルードし<iostream>、後者はインクルードしません。C ++標準[res.on.headers]に準拠

C ++ヘッダーには、他のC ++ヘッダーが含まれている場合があります。

私にとって、これは基本的に3つのコンパイラすべてが正しいと言います。

この問題は、TAがコンパイルしていないとマークした私の生徒の1人が提出したときに発生しました。もちろん行って修正しました。しかし、私はこのような今後の事件を防ぎたいと思います。では、3つの異なるコンパイラーでコンパイルして毎回チェックするのではなく、どのヘッダーファイルをインクルードするかを決定する方法はありますか?

私が考えることができる唯一の方法は、すべてのstd関数呼び出しに対して適切なインクルードが存在することを確認することです。しかし、何千行もある既存のコードがある場合、これを検索するのは面倒な場合があります。クロスコンパイラの互換性を確保するためのより簡単な/より良い方法はありますか?

3つのコンパイラの例:https : //godbolt.org/z/kJhS6U


6
文字列std::stoiを処理するためのものであることを覚えている場合は、それを含めるのに適したヘッダーであると推測できます。または、あなたに教えてくれる良いリファレンスを検索することもできます。また、常に明示的にヘッダーファイルを含めることをお勧めします。これにより、移植性のない実装固有の動作に依存する必要がなくなります。<string>
一部のプログラマー、

3
最善の方法は、他のプラットフォームに行く前にcppreferenceに行くことです。彼らはそこにかなり詳細なものを持っています。
Siddharth、

1
コードを記述するときに適切なヘッダーを含めます。つまり。を含むコードを記述した瞬間にstd::stoi、すぐに#include <string>存在することも確認します。
Sander De Dycker

3
一般的なケースでは、これは難しい問題です。ただし、欠落している標準ライブラリインクルードについて話している場合、通常の方法は実際に使用されているすべての関数呼び出し/型を調べることです。
Max Langhof

1
@ skratchi.atでは、コードが標準に準拠している限り、どのコンパイラを使用してもかまいません。4年後、これが問題となったのはこれが初めてです。
ChrisMM

回答:


14

クロスコンパイラの互換性を確保するためのより簡単な/より良い方法はありますか?

巨大なコードベースがあり、これまでこれを行っていない場合、これは常に面倒な作業になりますが、インクルードの修正を終えたら、簡単な手順に固執することができます。

などの標準機能を使用する新しいコードを作成する場合は、std::stoiその名前をGoogleに挿入し、cppreference.comの記事に移動して、上部を見て、どのヘッダーで定義されているかを確認します。

それがまだ含まれていない場合は、それを含めます。仕事完了!

(これには標準を使用できますが、それほどアクセス可能ではありません。)

次のような安価で移植性のないハックを好むために、すべてを解体しようとする誘惑に負けないでください<bits/stdc++.h>


tl; dr:ドキュメント


3
公平を期すために、すべてを効果的に記憶し、それを調べる必要がなくなると、それはかなり洗練

5
@JosephWood:特定の関数がどのヘッダーであるかがわからない場合は、関数を調べて仮定を再確認する必要がある可能性があります。そのため、どのヘッダーが属しているかを見つけるのに余分なことは必要ありません。時間。
DevSolar

1
@JosephWoodのように、私はまた、より多くの経験を持つ人々がより良い方法を持っていることを望んでいました。ほとんどのSTL関数にどのヘッダーを含めるかはわかっていますが、すべての関数を調べるよりも生徒に教える簡単な方法があることを望んでいました:P
ChrisMM

1
@ChrisMMには、include-what-you-useなどのツールがあります。それらの正確性は保証できません(実際に手動での作業が必要になることもあります)が、それはまったく問題ありません。
気まぐれ

4
@ChrisMMドキュメントを参照するように生徒に教えることは、非常に重要です。何千人もの人々が毎日このサイトにアクセスし、彼らがそうすべきだという地上の考えはありません。ドキュメントを使用することより簡単に/より良い方法。
にオービットの軽量レース

-1

ドキュメントを確認して手動で(苦痛で時間がかかる)行う以外に、それを行うためのツールを使用できます。

インポートを整理できるVisual StudioでReSharperを使用できます(実際、ReSharperなしのVSはあまり使用できません)。includeが欠落している場合は追加することをお勧めします。includeが付いている古い行は、淡い色で表示されます。

または、この機能も備えたCLion(すべてのプラットフォームで利用可能)を使用できます(実際、これはJetBrainsと同じメーカーです)。

includeと呼ばれるツールもありますが、その目的は前方宣言を利用することです。私はそれを使用したことはありません(個人的には、チームの仲間が私たちのプロジェクトで使用しました)。


動作する場合、他のヘッダーが既に含まれている場合、clionは正しいヘッダーの自動組み込みを行いません(つまり、iostreamがすでに含まれている場合、ここでは文字列を提案しません)IIRC
RiaD
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.