2
template <typename T>
void list<T>::copyAll(const list &l)
{
    if(l.isEmpty()) //if the list-to-copy is empty, we're done
    {
        first = last = NULL;
    }
    else
    {
        node *toFollow = l->yhjfrtydfg;
        node *whatever = l.asfqwejfq3fqh23f8hq23r1h23017823r087q1hef;

        while(toFollow != NULL)
        {
            T *newO = new T(*(toFollow->o));
            T here = *newO;
            insertBack(&here);
            toFollow = toFollow->next;
        }
    }
}

このプログラムは (残りのプログラムと共に) コンパイルされますが、2 行のnode *toFollow = l->yhjfrtydfg;node *whatever = l.asfqwejfq3fqh23f8hq23r1h23017823r087q1hef;は明らかにクレイジーな入力です。他のエラーがキャッチされるので、それは奇妙です。何か助けはありますか?

4

3 に答える 3

6

テンプレートパラメータに依存する名前は、テンプレートがインスタンス化された後にのみ解決されます。いずれの場合も、依存しない名前のみが解決されます。

C ++は、この「2フェーズルックアップ」を作り出しました。フェーズ1は最初に解析されるときであり、フェーズ2はインスタンス化時間です。

例えば:

template <typename T>
void frob() {
    foo = 5; // non-dependent, name must exist at this point
    T bar;
    bar.frobnicate = 7; // dependent, name is looked up upon instantiation

    bar->is->a.funny(T::hing); // dependent, likewise looked up later
}
于 2012-12-03T11:40:52.610 に答える
6

「従属名」 (テンプレートで使用される名前で、その意味はテンプレート パラメーターに依存します) は、テンプレートが定義されたときではなく、インスタンス化されたときにのみ解決されます。テンプレートをインスタンス化しない場合は、構文的に正しい限り、好きなクレイジーな名前を含めることができます。

インスタンス化された場合、プログラムはコンパイルに失敗します。

list<int> l;
l.copyAll(l); // ERROR
于 2012-12-03T11:38:00.283 に答える
2

存在しないメンバーはあなたの心配のほとんどではありません.一部の T が実際にそれらのメンバーを持っている可能性があるため、コンパイラは文句を言いません. あなたの混乱の根本的な原因は、コンパイラが識別子を他のものと同じように見なすことです.誰もこれを使用しないというあなたの認識だけであり、明らかに入力を「クレイジー」にするタイプ T はありません。それはまったくクレイジーではありません。これは単なる識別子です。

        T newO = new T(*(toFollow->o));
        insertBack(&newO);
        toFollow = toFollow->next;

完全に完全に壊れています。まず、動的に T を割り当ててから、スタック割り当ての T を構築しようとしますか? このように動作する T はありません。次に、スタック割り当てオブジェクトへのポインターを保持します。

于 2012-12-03T11:41:41.787 に答える