web-dev-qa-db-ja.com

名前空間stdでテンプレートクラスを前方宣言する方法は?

#ifndef __TEST__
#define __TEST__

namespace std
{
    template<typename T>
    class list;
}

template<typename T>
void Pop(std::list<T> * l)
{
    while(!l->empty())
        l->pop();
}

#endif

私のメインでその機能を使用しました。エラーが発生します。もちろん、std::list(アロケーターだと思う)にはもっと多くのテンプレートパラメーターがあることを知っています。しかし、それは重要なことです。前方宣言できるように、テンプレートクラスの完全なテンプレート宣言を知っている必要がありますか?

編集:私は以前にポインタを使用していませんでした-それは参照でした。ポインターで試してみます。

128
nakiya

問題は、テンプレートクラスを前方宣言できないということではありません。はい、すべてのテンプレートパラメータを知っている必要がありますおよびそれらのデフォルト

namespace std {
  template<class T, class Allocator = std::allocator<T>>
  class list;
}

しかし、namespace stdでそのような前方宣言を行うことも、標準では明示的に禁止されています。onlyに入れることが許可されているものstdはテンプレートですspecialisation、通常はユーザー定義型のstd::less。必要に応じて、他の誰かが関連するテキストを引用できます。

#include <list>だけで、心配する必要はありません。

ああ、偶然にも、二重アンダースコアを含む名前は実装で使用するために予約されているため、TEST_Hの代わりに__TEST__のようなものを使用する必要があります。警告やエラーは生成されませんが、プログラムに実装定義の識別子との衝突がある場合、正しくコンパイルまたは実行されることは保証されません:不正な形式です。また、アンダースコアで始まり、その後に大文字が続く名前なども禁止されています。一般的に、どの魔法を扱っているのかわからない限り、下線で始めないでください。

139
Jon Purdy

私はその問題を解決しました。

C++(Eclipse Juno)でのネットワークシミュレーション用にOSIレイヤー(スライダーウィンドウ、レベル2)を実装していました。フレーム(テンプレート<class T>)とその状態(状態パターン、前方宣言)がありました。

解決策は次のとおりです:

*.cppファイルには、転送するヘッダーファイル、つまり.

ifndef STATE_H_
#define STATE_H_
#include <stdlib.h>
#include "Frame.h"

template <class T>
class LinkFrame;

using namespace std;

template <class T>
class State {

  protected:
    LinkFrame<int> *myFrame;

}

そのcpp:

#include "State.h"
#include "Frame.h"
#include  "LinkFrame.h"

template <class T>
bool State<T>::replace(Frame<T> *f){

そして...別のクラス。

20
user1638075

前方宣言には、完全なテンプレート引数リストを指定する必要があります。

10
Grozz