C++ 创建向量为键、自定义类为值的映射时出现问题

C++ 创建向量为键、自定义类为值的映射时出现问题,c++,vector,maps,C++,Vector,Maps,我创建了下面的抽象类来评估简单游戏的棋盘位置。抽象类被每个派生类覆盖,因此game.h中只定义了求值函数 我试图通过使用备忘录使我的程序更高效,但我无法使我的地图正常工作。编译器为行结果[board]=best抛出一个错误。此行试图将映射到当前线路板(整数向量)的值设置为从该位置开始的最佳移动。Move是我创建的一个类,它只包含一个分数、一个要删除以制作下一个棋盘的数字,以及要从中删除数字的索引(堆) “results[board]=best”的编译器错误表示没有与move::move()匹配的

我创建了下面的抽象类来评估简单游戏的棋盘位置。抽象类被每个派生类覆盖,因此game.h中只定义了求值函数

我试图通过使用备忘录使我的程序更高效,但我无法使我的地图正常工作。编译器为行结果[board]=best抛出一个错误。此行试图将映射到当前线路板(整数向量)的值设置为从该位置开始的最佳移动。Move是我创建的一个类,它只包含一个分数、一个要删除以制作下一个棋盘的数字,以及要从中删除数字的索引(堆)

“results[board]=best”的编译器错误表示没有与move::move()匹配的函数调用。我不理解这个错误,因为我没有尝试创建新的移动,只是存储当前的最佳移动。我尝试过创建一个临时移动并存储它,所以我知道这是不正确的

最后一点-代码在没有那行代码的情况下可以完美编译和运行,因此我知道算法和所有子类都可以正常工作。任何帮助都将不胜感激

// VIRTUAL FUNCS
// All virtual functions must be overridden by subclasses

virtual ~game(){ }

// initialize
virtual void initialize( int numPlayers, std::vector<int> board ) = 0;


// gameHasEnded
virtual bool gameHasEnded( std::vector<int> board ) const = 0;

// display
virtual void display( std::vector<int> board ) const = 0;

// makeNewBoard
virtual std::vector<int> makeNewBoard( std::vector<int> currBoard, move m ) = 0;

// generateMoves
virtual std::vector< move >  generateMoves( std::vector<int> currBoard ) = 0;

// compare
virtual move compare( std::vector<int> board1, std::vector<int> board2 ) = 0;

// NON-VIRTUAL FUNCS

//
// Name:         evaluate
// Description:  Evaluates a given board position. Determines whether
//                 or not the current position is a winning position
//                 or a losing position. A winning position is
//                 designated by a 1, a losing by a -1.
// Modifies:     The board and the score.
// Returns:      The best possible move from this position.
//                
move evaluate(  std::vector<int> board, int multiplier = 1, int currScore = -100) {

  // Base case is defined by subclasses
  if( gameHasEnded( board ) ) {
    move toReturn(multiplier, 0);
    return toReturn;
  } // end-if

  // If game is not over
  else {

    std::map<std::vector<int>,move>::iterator iter = results.find( board );
    if( iter != results.end() ) {
      return iter->second;
    }
    else {

      move best(-2,0);  // Just a place holder. Is overridden later.
      int s = 0;  // Stores the score

      std::vector<move> nextMove;
      // generate all possible boards from this position - defined by subclass
      nextMove = generateMoves( board );

      // For each board position
      for( int i = 0; i < ( (int)nextMove.size() ); ++i ) {
        std::vector<int> newBoard;

        // Create a new possible board state
        newBoard =  makeNewBoard( board, nextMove[i] );

        move dif = compare( board, newBoard );  // Get the move that was made
        move m(0,0);  // place holder
        m = evaluate( newBoard, multiplier*-1, currScore );  // recurse through all positions
        s += m.getScore();
        // If this is the best score so far
        if( m.getScore() > currScore ) {  

          m.setNumTake( dif.getNumTake() );  // get the move
          m.setPile( dif.getPile() );
          best = m;  // store the move
          currScore = m.getScore();  // update the score

        }

      }
      best.setScore( s );

      ////////////////////////////// THIS IS THE LINE THAT THROWS A COMPILER ERROR

      results[ board ] = best;

      //////////////////////////////////

      return best;  // return best move
    }
  }
    return move(2,2);  // dummy return. should never happen
  }
//虚拟函数
//所有虚拟函数都必须由子类重写
虚拟~game(){}
//初始化
虚拟空初始化(int numPlayers,std::vector board)=0;
//游戏结束
虚拟bool gamehasend(std::vector board)const=0;
//展示
虚拟虚空显示(标准::矢量板)常数=0;
//造船板
虚拟std::vector Makeneboard(std::vector currBoard,move m)=0;
//生成动作
虚拟std::vectorgenerateMoves(std::vector currBoard)=0;
//比较
虚拟移动比较(std::vector board1,std::vector board2)=0;
//非虚函数
//
//名称:评估
//描述:评估给定的电路板位置。决定是否
//当前位置是否为获胜位置
//或者是一个失利的位置。获胜的位置是
//由1指定,由-1指定。
//修改:棋盘和分数。
//返回:从该位置开始的最佳移动。
//                
移动评估(标准::向量板,整数乘数=1,整数分数=-100){
//基本情况由子类定义
if(游戏结束(董事会)){
移动到返回(乘数,0);
回归回归;
}//如果结束,则结束
//如果游戏还没有结束
否则{
std::map::iterator iter=results.find(board);
if(iter!=results.end()){
返回iter->second;
}
否则{
移动最佳(-2,0);//只是一个占位符。稍后将被覆盖。
int s=0;//存储分数
std::矢量下一步移动;
//从该位置生成所有可能的板-由子类定义
nextMove=生成移动(板);
//每个董事会职位
对于(int i=0;i<((int)nextMove.size());++i){
std::向量新板;
//创建一个新的可能的板状态
新板=制造新板(板,下一个移动[i]);
move dif=compare(board,newBoard);//获得所做的移动
移动m(0,0);//占位符
m=评估(新板,乘数*-1,currScore);//递归所有位置
s+=m.getScore();
//如果这是目前为止最好的成绩
如果(m.getScore()>currScore){
m、 setNumTake(dif.getNumTake());//开始移动
m、 setPile(dif.getPile());
best=m;//存储移动
currScore=m.getScore();//更新分数
}
}
最佳。设置核心;
//////////////////////////////这是引发编译器错误的行
结果[董事会]=最佳;
//////////////////////////////////
返回最佳;//返回最佳移动
}
}
返回移动(2,2);//虚拟返回。不应该发生
}
私人数据成员

std::map<std::vector<int>,move> results;
std::map结果;

})

如果使用运算符[],则需要默认构造函数


如果映射不包含键
的元素,则映射的运算符[]将构造一个新的默认对象并将其插入映射。只有这样,它才能对
best

进行赋值,在带有[]运算符的映射中用作值的任何类都必须能够使用默认构造函数创建

results[ board ] = best;
将执行以下操作

  • 用按键
    板创建一个默认
    移动()
  • 返回对该地址的引用
  • 通过指定
    最佳
    来覆盖默认移动

  • 步骤1失败。

    仅当使用运算符[]时,才需要默认构造函数。您可以使用find和insert将类用作没有默认构造函数的值,那么我只需要为move定义一个默认构造函数?这将允许创建一个临时移动,然后最好将其存储在上面,对吗?谢谢阿库塞特!我创建了默认构造函数,它工作得很好。@Mike:很高兴它工作了,但是如果您不想让Move拥有默认构造函数,可以使用映射函数put()。检查