-1

私が書いている C++ キューにテンプレートを実装するのに問題があります。コンパイラの問題を解決するのを手伝ってくれたら、とても助かります!

これが私のコンパイラ出力です:

a7_main.cpp:3:0 からインクルードされたファイル: Queue.h: メンバ関数 TYPE Queue::pushAndPop(TYPE) 内:

Queue.h:33:25: 警告: x の名前検索が変更されました [デフォルトで有効]

Queue.h:27:28: 警告: ISO 標準ルールの下でこの x に一致します [デフォルトで有効]

Queue.h:30:11: 警告: 古いルールの下でこの x に一致します [デフォルトで有効]

Queue.h: グローバル スコープ:

Queue.h:45:23: エラー: 引数リストのないテンプレート名キューの無効な使用

Queue.h: コピー コンストラクター Queue::Queue(Queue&) [TYPE = V2、Queue = Queue で]:

a7_main.cpp:56:19: ここからインスタンス化

Queue.h:41:5: エラー: Queue::pushAndPop(int) の呼び出しに一致する関数がありません

Queue.h:41:5: 注: 候補は:

Queue.h:27:28: 注: TYPE Queue::pushAndPop(TYPE) [TYPE = V2 の場合]

Queue.h:27:28: 注: 引数 1 の int から V2 への既知の変換はありません

これらの警告とエラーを理解しようとしましたが、マンネリ化してしまいました。これが私のコードです:

#if !defined QUEUE_SIZE
#define QUEUE_SIZE 30
#endif
using namespace std;

template <class TYPE> class Queue
{
 private:
  TYPE *array;
 public:
  Queue(Queue& other);
  Queue();
  ~Queue();
  Queue& operator=(Queue other);
  TYPE pushAndPop(TYPE x);
};

template <class TYPE> Queue<TYPE>::Queue()
{
  array=new TYPE[size];
}

template <class TYPE> Queue<TYPE>::~Queue()
{
  delete [] array;
}

template <class TYPE> TYPE Queue<TYPE>::pushAndPop(TYPE x)
{
  TYPE item = array[0];
  for(int x = 0; x<QUEUE_SIZE-1; x++){
    array[x]= array[x+1];
  }
  array[QUEUE_SIZE-1] = x;
  return item;
}

template <class TYPE> Queue<TYPE>:: Queue(Queue& other)
{
  int x;
  for(x=0; x<QUEUE_SIZE;x++){
    array[x] = other.pushAndPop(0);
  }
}

template <class TYPE> Queue& Queue<TYPE>:: operator=(Queue other)
{
  int x;
  for(x=0; x<QUEUE_SIZE;x++){
    array[x] = other.pushAndPop(0);
  }
}

編集:呼び出しコードは次のとおりです。

#include <ncurses.h>
#include <unistd.h>
#include "Queue.h"

//----------------------------------------------------

#define START_ROW (20)
#define START_COL (20)
#define SLEEP_MICROSECONDS ((1.0 / 20.0) * 1000000.0)

//----------------------------------------------------

// Simple storage for a row, column pair.
struct V2 {
  int row, col;
};

//----------------------------------------------------

// Some of this ncurses code is, unfortunately, copied from
// the man page without full understanding.
void configureNcurses()
{
  initscr();
  cbreak();
  noecho();
  nonl();
  intrflush(stdscr, FALSE);
  keypad(stdscr, TRUE);
  nodelay(stdscr, TRUE);
  curs_set(0);
  start_color();
  init_pair(1, COLOR_RED, COLOR_BLACK);
  init_pair(2, COLOR_GREEN, COLOR_BLACK);
  init_pair(3, COLOR_YELLOW, COLOR_BLACK);
  init_pair(4, COLOR_BLUE, COLOR_BLACK);
  init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
  init_pair(6, COLOR_CYAN, COLOR_BLACK);
  init_pair(7, COLOR_WHITE, COLOR_BLACK);
}

//----------------------------------------------------

// Draw centipede with sequence of foreground colors, or with
// background color, depending on "erase" flag.
// (Pass centipede by value to exercise copy constructor.)
void drawCentipede(Queue<V2> centipede, bool erase)
{
  int drawCharacter;
  int colorNumber;
  V2 currentPosition, dummyPosition;
  Queue<V2> centipedeCopy;

  // Make a copy of centipede to be consumed during drawing.
  // (Exercises assignment operator.)
  centipedeCopy = centipede;

  // Prepare to draw or erase, as requested.
  if (erase)
    drawCharacter = ' ';
  else
    drawCharacter = ' ' | A_REVERSE;

  // Consume centipede copy to obtain data for drawing.
  for (int i = 0; i < QUEUE_SIZE; ++i) {
    colorNumber = 1 + (i % 7);
    currentPosition = centipede.pushAndPop(dummyPosition);
    attron(COLOR_PAIR(colorNumber));
    mvaddch(currentPosition.row, currentPosition.col,
            drawCharacter);
    attroff(COLOR_PAIR(colorNumber));
  }
}

//----------------------------------------------------

// Update position based on arrow key input.
void updatePosition(V2& position, int inputChar)
{
    switch (inputChar) {
    case KEY_UP:
      --position.row;
      break;
    case KEY_DOWN:
      ++position.row;
      break;
    case KEY_LEFT:
      --position.col;
      break;
    case KEY_RIGHT:
      ++position.col;
      break;
    default:
      // (Ignore all other keys.)
      break;
    }
}

//----------------------------------------------------

main()
{
  Queue<V2> centipede;
  int currentDirection;
  int inputChar;
  V2 currentHead;

  // Configure ncurses.
  configureNcurses();

  // Fill queue (all centipede segments at start position).
  currentHead.row = START_ROW;
  currentHead.col = START_COL;
  for (int i = 0; i < QUEUE_SIZE; ++i)
    centipede.pushAndPop(currentHead);

  // Draw instructions and initial centipede.
  attron(COLOR_PAIR(2));
  mvaddstr(1, 3, "USE ARROW KEYS TO MOVE, CTRL-C TO QUIT");
  attroff(COLOR_PAIR(2));
  drawCentipede(centipede, false);
  refresh();

  // Process input until killed.
  currentDirection = KEY_RIGHT;
  while (true) {
    // Show current state, then check for input.
    usleep(SLEEP_MICROSECONDS);
    inputChar = getch();
    if (inputChar != ERR)
      currentDirection = inputChar;

    // When input received, erase old centipede.
    drawCentipede(centipede, true);

    // Then use new input to update centipede.
    updatePosition(currentHead, currentDirection);
    centipede.pushAndPop(currentHead);

    // Then draw new centipede, and refresh.
    drawCentipede(centipede, false);
    refresh();
  }

  // Clean up ncurses.  (Re-display cursor.)
  curs_set(1);
}

//----------------------------------------------------
4

1 に答える 1

1
template <class TYPE> Queue<TYPE>::Queue()
{
  array=new TYPE[size];
}

とはsize?

template <class TYPE> TYPE Queue<TYPE>::pushAndPop(TYPE x)
                                                   ^^^^^^
{
  ...
  for(int x = 0; ...) {
      ^^^^^

ここには競合する名前があります。それは悪い考えです。パラメーターまたはループ変数に別の名前を付けます。

template <class TYPE> Queue<TYPE>:: Queue(Queue& other)
                                          ^^^^^^

これはどのようなものをQueue受け入れますか?のみの場合は、それQueue<TYPE>を正確に指定する必要があります。他の型を取ることができる場合は、別のテンプレート パラメーターが必要になります (ただし、ここでは意味がありません)。

template <class TYPE> Queue& Queue<TYPE>:: operator=(Queue other)
                      ^^^^^^                         ^^^^^

constここで同じ発言に加えて、パラメーターは (おそらく) 参照によって取得する必要があるように見えます。

array[x] = other.pushAndPop(0);
                            ^

(2 回。)TYPEのようなものでない限りint、これは意味がありません。pushAndPopを受け取るオーバーロードはありませんint

あなたのコードを正しく理解していれば、コピー コンストラクターとコピー代入演算子の両方が引数を破棄します。それはとても驚くべきことです。引数は によって取得されconst&、読み取られるだけである必要があります。

于 2013-05-22T06:13:46.810 に答える