5

C++ で名前空間とテンプレートを処理しようとしています。次のコードを MSVC でコンパイルすることはできますが (警告やエラーは発生しません)、CYGWIN/GCC を使用したさまざまな順列でまったくうまくいきません。どんな助けでも大歓迎です。

ヘッダー ファイルで、テンプレート化されたサブクラスを次のように宣言します。

#include <gdal.h>
namespace sfms {

template <class _type, GDALDataType _gdal> class SmfsGrid_Typed : public SfmsGrid_Base {
public:
  SmfsGrid_Typed();
  SmfsGrid_Typed(const SmfsGrid_Typed<_type, _gdal> *toCopy);
  SmfsGrid_Typed(std::string filename);
  virtual ~SmfsGrid_Typed();
  virtual bool OpenRead();
  virtual bool OpenWrite();

protected:
  _type m_nodata_value;

  virtual SfmsGrid_Base *New() const;
  virtual SfmsGrid_Base *New(SfmsGrid_Base *toCopy) const;
  virtual void initCopy(SfmsGrid_Base *copy) const;
};

template SmfsGrid_Typed<double, GDT_Float64>;
template SmfsGrid_Typed<float, GDT_Float32>;
template SmfsGrid_Typed<int, GDT_Int32>;

typedef SmfsGrid_Typed<double, GDT_Float64> SmfsGrid_Double;
typedef SmfsGrid_Typed<float, GDT_Float32> SmfsGrid_Float;
typedef SmfsGrid_Typed<int, GDT_Int32> SmfsGrid_Int;
}

ソース ファイルで、特殊なテンプレート クラスを次のようにインスタンス化します。

void hi_there() {
//...
sfms::SmfsGrid_Typed<int, GDT_Int32> *grid = new sfms::SmfsGrid_Typed<int, GDT_Int32>(filey);
//...
sfms::SmfsGrid_Int *grid2 = new sfms::SmfsGrid_Int(filey);
//...
}

GDALDataType は列挙型ですが、それは問題ではないようです。

名前空間の内外でクラス宣言を試みましたが、成功しませんでした。

テンプレートの実装を含むソース ファイルは、両方のコンパイラで正常にコンパイルされます。

明示的なテンプレートのインスタンス化を削除して、関連する C++ ソース ファイルをインクルードしようとしましたが、これも楽しみではありませんでした。

「template」、「typename」、および「typedef」キーワードをさまざまな場所 (テンプレート化されたクラス def'n およびオブジェクトを作成しようとする場所) で試しましたが、成功しませんでしたが、さまざまな興味深い、しばしば誤解を招くようなエラー メッセージが表示されます。次のような GCC:

error: 'SmfsGrid_Typed' is not a member of 'sfms'

それが明らかにあるとき!:) いずれにせよ、このコードを MSVC から GCC に移植するためのヘルプは役立ちます。

ありがとう!

4

1 に答える 1

3

明示的なテンプレートのインスタンス化が間違っているようです。で置き換えてみてください

template class SmfsGrid_Typed<double, GDT_Float64>;
template class SmfsGrid_Typed<float, GDT_Float32>;
template class SmfsGrid_Typed<int, GDT_Int32>;

(追加された class キーワードに注意してください)

于 2013-02-03T07:39:17.083 に答える