4

私が書いたいくつかのコードで、本当に厄介な問題が発生しています。スタックオーバーフローで同じ問題を抱えている他の人を見つけ、解決策を試しましたが、うまくいきませんでした。

私が使用しているいくつかの一般的な STL 型を型定義しますが、マップを型定義しようとする場合を除いて、他の型に問題はありません。テスト プログラムにヘッダーを含めると、"some_file.h:83: error: expected initializer before '<' token" エラーが発生します。

ヘッダー (some_file.h) の重要な部分は次のとおりです。

#ifndef SOME_FILE_H
#define SOME_FILE_H
// some syntax-correct enums+class prototypes
typedef std::string str;
typedef std::vector<Column> col_vec;
typedef col_vec::iterator col_vec_i;
typedef std::vector<Row> row_vec;
typedef row_vec::iterator row_vec_i;
typedef std::vector<str> str_vec;
typedef str_vec::iterator str_vec_i;
typedef std::vector<Object> obj_vec;
typedef obj_vec::iterator obj_vec_i;
typedef std::map<Column, Object> col_obj_map; // error occurs on this line
typedef std::pair<Column, Object> col_obj_pair;

some_file.cpp のインクルードは次のとおりです。

#include <utility>
#include <map>
#include <vector>
#include <iostream>
#include <string>
#include <stdio.h>
#include <cc++/file.h>
#include "some_file.h"

テスト ファイルには、文字列、ベクター、および my ファイルがこの順序で含まれているだけです。hello world のようなことを行う main メソッドがあります。

面白いことに、テンプレート化されたクラスをすぐにまとめて (" std::map<Column..." を " "に置き換えてhello<Column...) 問題がどこにあるかを調べたところ、問題なく動作しました。

<' ' 演算子のないクラスを使用している場合は、マップに必要な演算子のオーバーロードを既に作成しています。

4

4 に答える 4

14

コンパイラはマップが何であるかを認識していないため、この問題が発生しています。マップ ヘッダーがまだ含まれていないため、わかりません。ヘッダーは、STL テンプレート (文字列、ベクター、マップ、およびペア) を使用します。ただし、それらは定義されておらず、定義されている場所への参照もありません。テスト ファイルが文字列やベクトルではなくマップ上で barfs を実行する理由は、some_file.h の前に文字列とベクトルのヘッダーを含めるため、文字列とベクトルは定義されていますが、マップは定義されていません。マップのヘッダーを含めると機能しますが、ペアについて文句を言うことがあります (特定の STL 実装でマップのヘッダーにペアが含まれていない限り)。

一般に、最適なポリシーは、独自のヘッダーで使用するすべてのタイプに適切な標準ヘッダーを含めることです。したがって、 some_file.h には、少なくとも次のヘッダーが必要です。

#include <string>
#include <map>
#include <utility> // header for pair
#include <vector>

このアプローチの欠点は、プリプロセッサが毎回各ファイルをロードし、条件付きインクルード処理を実行する必要があること#ifdefです#endif。そのため、数千のファイルがあり、各ファイルに数十のインクルードがある場合、コンパイル時間が大幅に長くなる可能性があります。 . ただし、ほとんどのプロジェクトでは、ヘッダーのインクルードを手動で管理しなければならないという追加の煩わしさは、コンパイル時間のわずかな増加に値しません。そのため、Scott Meyers の効果的な STLブックには、項目 #48として「常に適切なヘッダーを #include する」という記述があります。

于 2009-08-04T04:28:00.580 に答える
5

#include <map>ヘッダーファイルにどこかにありますか?

それを入れて、少なくともそれが機能するかどうかを確認してください。とにかくそうするべきです。

于 2009-08-04T04:11:23.710 に答える
5

これらのインクルードの一部をヘッダー ファイルに移動する必要があります。これらは、typedef ステートメントの前に配置する必要があります。

すなわち

#include <map>
#include <string>
#include <map>

そうしないと、メイン プログラム ソース ファイルの #include "some_file.h" インクルード ディレクティブの前にこれらのインクルードを配置しない限り、some_file.h を含む他のもの (メイン プログラムなど) はそれらが何であるかを認識できません。これを行えば、問題は解決するはずです。

于 2009-08-04T04:16:26.307 に答える
0

何人かの人が指摘しているように、コンパイラはマップの定義を見つけていません。マップヘッダーが含まれているように見えるので、他に2つの考えられる原因が考えられます。

  1. std mapヘッダーの代わりに、mapという別のヘッダーファイルがロードされています。これはありそうもないと思います。
  2. もう1つのヘッダーは、マップを別のものに#defineすることです。

どちらかをチェックする1つの方法は、後処理されたファイル、つまりCプリプロセッサを介して実行された後、コンパイルされる前のソースファイルをコンパイラに生成させることです。これで、問題のある行を見つけて、マップタイプが別のものに置き換えられているかどうかを確認できるはずです。また、ファイルを検索して、#includeがどのヘッダーに含まれているかを確認できるはずです。

後処理されたファイルを生成する方法はコンパイラに依存します-コンパイラのドキュメントでcmd-lineフラグを確認してください。

于 2009-08-04T05:54:10.897 に答える