2

この段階ではかなり古い、妥当なサイズのC ++アプリケーションがあるので、いくつかの癖があります。

これらの癖の1つは、標準化前の標準ライブラリを使用するC++コンパイラをどのように処理するかです。標準に準拠したコンパイラとこの1つの非準拠のコンパイラの違いを解決するためのヘッダーファイルが1つあります。さまざまな理由から、このコンパイラのサポートを停止することはできません。

#include <vector>
#include <set>
#if defined(NO_STD_LIB)
    #include <iostream.h>
#else
    #incude <iostream>

    using std::string;
    using std::cout;
    using std::vector;
    using std::cout;
#endif

これは次のように使用します

#include stl.h
int main() {
    vector<string> foo;
    .....
    return 0;
}

このアプローチには2つの主な問題があります。

  1. std.hを含む各コンパイルユニットは、多くの不要なコードをコンパイルする必要があります(そして、コンパイル時間を可能な限り短縮しようとしています)。
  2. グローバル名前空間は、通常はstd名前空間にあるほとんどすべてのもので汚染されます。

コードクリーンアッププロジェクトの一環として、これらの両方の点に対処したいと思います。最初のものは本当にこれを行うためのより重要な理由です。

この古いコンパイラをサポートする必要があるため、コードは常に、標準ライブラリで公開されているものと名前が衝突しないようにする必要があります。したがって、ポイント2は実際には関係ありませんが、次の場合に機能するソリューションが必要です。最終的にサポートをやめることができれば。

これまでの私の考えは、スーパーヘッダーを小さなヘッダーのセットに分割することです。たとえば、stl_vector、stl_iostream、stl_setなど。この方法では、関心のある標準ライブラリの部分のみを含めることができます。これらのファイル名は、stdヘッダーのパターンに従いますが、プレフィックスを簡単に検索できます。したがって、問題のあるコンパイラをダンプするときが来たら、プレフィックスを検索して削除するのは簡単です。

これで問題1は簡単に修正できると思います。

私の本当の問題は問題2を修正することです。私はこのような何かをすることを考えました

#if defined(NO_STD_LIB)
    #include <iostream.h>
    #define std
#else
    #include <iostream>

次に、次のようにコーディングできます。

#incude "stl_iostream"

int main() {
  std::string foo("bar");
  std::cout << foo << std::endl;
}

そして、それはほとんどうまくいきました。標準の名前空間がなかった場合、#definestdはstd::stringを::stringに分解し、生活は良好でした。

次に、恐ろしい「usingnamespacestd;」を使用した.ccファイルでこれを試しました。そして、それが「名前空間の使用」になるため、コンパイルエラーが発生します。これは明らかに機能しません。

これで、「名前空間std;を使用して」と書くことを禁止できましたが、ヘッダーでは避ける必要がありますが、多くのSTLクラスを多用している.ccファイルで役立つ場合があります。

それで、最後に、質問に。この問題に対処するための標準的なイディオムはありますか?または、これに対処する標準的な方法がない場合、先行標準の標準ライブラリを使用するコンパイラをサポートするためにどのようなトリックを使用しますか。

プリコンパイル済みヘッダーを使用してコンパイル速度の問題を解決することを考えましたが、さまざまなコンパイラを対象としており、すべてのコンパイラでこれを機能させるための努力は、時間をかける価値がないことを意味する場合があります。

不適合コンパイラを削除するようにアドバイスする回答は人気があるかもしれませんが、これは現在私たちができないことであるため、受け入れられません。

4

1 に答える 1

17

あなたが試すことができます:

#if defined(NO_STD_LIB)
namespace std {
    using ::string;
    using ::cout;
    using ::vector;
    using ::cout;
}
#endif

その後、std::string動作します。

using namespace ::;ディレクティブがその言語で存在していれば、はるかに良かったでしょう。しかし、そうではありません。

于 2009-12-20T15:59:52.503 に答える