1

テンプレートを使用したクラスStackがあり、そのメソッドの1つは「push」です。これは次のように記述されています。

template <class T>
void Stack<T>::push(T _data){
    Node<T>* temp = new Node<T>;
    temp->data = _data;
    temp->next = head;
    head = temp;
}

スタックは、、、、...intでうまく機能します。doublestringchar

prog.cpp:32: note: synthesized method ‘Node<Tree>::Node()’ first required here

データ型としてクラス「Tree」を使用する場合。なぜ「文字列」では機能するが「ツリー」では機能しないのかわかりません。どちらもクラスであり、プリミティブ型ではありません。

http://ideone.com/NMxeF (他のエラーは無視してください。私のIDEでは、32行目で1つのエラーといくつかの警告しか表示されません)

ヘルプ!

4

2 に答える 2

4

実際のコードを読んだ後で編集します(上記の「注」は、実際の問題についてかなり誤解を招く可能性があります)。

を使用しようとしているコードを見ると、ノードテンプレートにTのインスタンスが含まれているため、new Node<T>;Tのデフォルトコンストラクター(この場合は)が必要です。Tree

struct Node {
    T data;    // <--- instance of T, not being initialized in your code.
    Node *next;
};

Treeにはデフォルトのコンストラクターがないため、失敗します(メモには、デフォルトのコンストラクターが必要になる場所が示されています)。

それを修正する方法については、いくつかの選択肢があります。最も明白なのは、Tの実際のインスタンスを含むのではなく、Nodeへのポインタまたは参照のいずれかを保持することです。T

もう1つは、Nodeのコンストラクターに(おそらくconst)Tへの参照を取得させ、そのTをノードにコピーすることです。

class Node { 
    T data;
    Node *next;
public:
    Node(T const &dat) : data(dat), next(0) {}
};

これら2つのアプローチのどちらを選択するかは、かなり基本的なことです。ノードにTへのポインタ/参照を格納させる場合、ノードが存在する限り、渡されたオブジェクトが有効であり続けることを保証するためにコードを呼び出す責任があります。ノードと呼び出し元のコードは、Tの単一インスタンスへのアクセスを共有します。

対照的に、渡されたオブジェクトをノードにコピーすると、が破棄されるときにこのコピーがNode破棄されます。ノードに渡した元のT(この場合はツリー)は、呼び出し元のコードのNode責任を負い、そのコピーの責任を負います。

通常の場合、後者を好む傾向があります。これにより、よりクリーンなセマンティクスが提供され、データの所有権が明確に保たれます。ただし、ツリーの場合、回避できるのであれば、ツリー全体をノードにコピーしたくないでしょう。Node<shared_ptr<Tree> >妥協点の1つは、代わりにのようなものを使用することです。shared_ptrは、少数の種類のオブジェクトと状況にのみ適したノードを作成することを避けながら、高速かつ安価にコピーを続けることができます。これはまた、元のオブジェクトへの共有アクセスを提供するポインターのみを格納していることをかなり明確にします。

于 2012-04-14T02:13:55.997 に答える
4

のデフォルトコンストラクタはありますTreeか?そうでない場合は、それが問題である可能性があります。ノードは、を呼び出すときにデフォルトで構築される必要がdataあるタイプをそのメンバーに保持します。Treenew Node<Tree>

修正するには、Nodeのコンストラクターを変更datanextてパラメーターとして使用できるため、テンプレートタイプにデフォルトのコンストラクターは必要ありません(代入演算子を使用できるようにする必要があります)。

于 2012-04-14T02:14:40.923 に答える