3

コンパイラエラーを発生させる単純なコードがあります。Visual StudioのWindows環境でこれをコンパイルして実行することに問題はありませんでしたが、Linuxではgccを使用して問題が発生しています。gcc 4.4.5を使用していて、-std = c++0xディレクティブを使用していることに注意してください。

このコードスニペットはヘッダーファイルfile_handling.hにあり、必要なすべてのライブラリ(ベクトル、文字列、fstreamなど)が含まれています。変数'output_file'はLogFileオブジェクトのメンバーであり、他の場所で適切にチェック/インスタンス化などされます。コード自体は簡単です。それが私が困惑している理由です。

template <typename T> void LogFile::put(std::string const & header, std::vector<T> const & data) {

  output_file << header << " " << std::scientific << data[0] << std::endl;

  for (std::vector<T>::const_iterator value = (data.begin()+1); value < data.end(); ++value) {
           output_file << *value << std::endl;
  }

}

コンパイラーは次のように述べています。

In file included from file_handling.cpp:2:
file_handling.h: In member function 'void LogFile::put(const std::string&, const std::vector<T, std::allocator<_Tp1> >&)':
file_handling.h:132: error: expected ';' before 'value'
file_handling.h:132: error: 'value' was not declared in this scope
make: *** [file_handling.o] Error 1

gccが「value」のin-situ宣言をconst_iteratorとして認識しないのはなぜですか?健全性チェックとして次のことを試しました。

template <typename T> void LogFile::put(std::string const & header, std::vector<T> const & data) {
  std::vector<T>::const_iterator value;
  output_file << header << " " << std::scientific << data[0] << std::endl;

  for (value = (data.begin()+1); value < data.end(); ++value) {
           output_file << *value << std::endl;
  }

}

そして、まったく同じコンパイラレポートを受け取ります。これは単純に見え、Visual Studioで正常に機能しているとすると、gccやLinux環境について何が欠けているか誤解されていますか?

4

1 に答える 1

5

正しい形式は次のとおりです。

template <typename T> void LogFile::put(std::string const & header, std::vector<T> const & data) {

  output_file << header << " " << std::scientific << data[0] << std::endl;

  for (typename std::vector<T>::const_iterator value = (data.cbegin()+1); value != data.cend(); ++value) {
           output_file << *value << std::endl;
  }

}

typenameの追加、およびbegin()とend()からcbegin()とcend()への変更に注意してください。

テンプレートタイプを使用する場合は、typenameが必要です。begin()とend()はconst_iterators用ではありません。

編集:どうやらbegin()とend()はconst_iteratorsを返します。私はその目的でそれらを使用したことはなく、明確性と強制リターンタイプが追加されたため、常にcbegin()とcend()を使用していました。それぞれに私は推測します。

注:簡単にするために、c++11の新しいautoキーワードを使用できます。

template <typename T> void LogFile::put(std::string const & header, std::vector<T> const & data) {

  output_file << header << " " << std::scientific << data[0] << std::endl;

  for (auto value = (data.cbegin()+1); value != data.cend(); ++value) {
           output_file << *value << std::endl;
  }

}
于 2012-09-03T03:56:57.820 に答える