0

std :: multimapをメンバーとして使用するテンプレートクラスを作成していて、コンパイルエラーが発生します。

LocTree.h:

#pragma once
#include <map>

template <class Loc, class T>
class LocTree
{
public :
         typedef std::multimap<typename Loc, typename T> TreeType;

        LocTree( void );
        ~LocTree( void ) { };
private :
        TreeType db;
};

LocTree.cpp:

#include "StdAfx.h"
#include "LocTree.h"

LocTree< class Loc, class T>::LocTree()
{
}

コンパイルエラー(VC2005から):

Error     1     error C2079: 'std::pair<_Ty1,_Ty2>::first' uses undefined class 'Loc'     c:\program files (x86)\microsoft visual studio 8\vc\include\utility     53
Error     2     error C2079: 'std::pair<_Ty1,_Ty2>::second' uses undefined class 'T'     c:\program files (x86)\microsoft visual studio 8\vc\include\utility     54

関数定義を.hに入れることができることは知っていますが、合法であれば、それらを別々に保つことを望んでいます。この(おそらく初心者の)問題を修正するにはどうすればよいですか?

4

3 に答える 3

4

コンストラクターの定義は次のようになります。

template<class Loc, class T>
LocTree<Loc,T>::LocTree()
{
}

また、それらを別々に保つことを望んでいます...-しないでください-あなたはあなたの時間を無駄にしています。それらを分離しておく唯一の方法は、あなたが含めた別のヘッダーに定義を入れることです。したがって、技術的には、これらは別個のものですが、実装は引き続き表示されます。

于 2012-04-17T08:04:56.157 に答える
3

2点。最初は:何ですか:

typedef std::multimap<typename Loc, typename T> TreeType;

意味するはずですか?そこで何が行われているのかわかりませんtypename。私はあなたが欲しいと思います:

typedef std::multimap<Loc, T> TreeType;

次に、クラスの外部でクラステンプレートのメンバー関数を定義する場合、構文は次のようになります。

template <typename Loc, typename T>
LocTree<Loc, T>::LocTree()
{
}

template<...>つまり、この句を繰り返す必要があります。(使用するか使用するtypenameclass<...>無関心です。クラスである必要はないので、私が知っているほとんどの人はtypename、これが意味に近いので、好みます。)

実装を分離しておくことに関して:C++のテンプレートはこの点でいくらか壊れています。コンパイラの依存関係を回避することはできません。ただし、実装を定義から分離したままにしておきたい場合もあります。通常の手法は、テンプレートの実装を別のファイル(.tccたとえば)に配置し、これをヘッダーから含めることです。

于 2012-04-17T08:43:00.640 に答える
2

テンプレートの実装を分離しておくことは、簡単なことではありません。

一般的にはできません。つまり、テンプレート化されたパラメータが「何でも」である可能性がある場合は実行できません。

テンプレート化されたパラメータの特定の限定されたサブセットに対して、たとえば次のようなテンプレートがある場合に実行できます。

template< bool B > class Foo;

次に、以下を指定できます。

extern template class Foo<true>;
extern template class Foo<false>;

これは、テンプレートの「インスタンス化」と呼ばれ、他の場所で実装されたtrueとfalseの値の実装があることをコンパイラーに指定します。

これは、テンプレート化されたパラメーターがタイプであり、特定のサブセットに制限されている場合にも実行できます。

次に、コンパイルユニット内で、テンプレートの実装を定義し、上記と同じ方法を使用して、「extern」という単語を使用せずに、テンプレートをもう一度インスタンス化します。

これは、非常に限られたパラメータータイプのサブセットのみが許可される、データベースのストアドプロシージャ呼び出しのパラメーター値を設定するメンバー関数を作成する場合の実動コードで行いました。タイプが非常に限られたサブセットである場合、これがコードを分離し、多くの実装の詳細を隠すのに役立つ場合は、先に進んで同じことを行います(実装がデータベースで行われる場合は、実行する価値があります)。

別のヘッダーで実装を提供する「中間」の根拠があります。この規則についてよく見_i.hたり、類似したりしてから、必要な場合にのみこのヘッダーを含めて、テンプレートをインスタンス化します。したがって、クラスFooを作成する場合は、ヘッダーで、実装とインスタンス化のためのファイルである私のfooクラスの「extern」宣言を使用しますFoo.hFoo.cpp#include_i.h

構文については、テンプレート実装ファイルで次を使用します。

template<class Loc, class T>
LocTree<Loc,T>::method(...)
{
  ...
}
于 2012-04-17T08:23:17.877 に答える