簡體   English   中英

C ++設置方法:函數'setCost'不可行:'this'參數的類型為'const value_type'

[英]C++ set method: function 'setCost' not viable: 'this' argument has type 'const value_type'

我無法通過set方法將值設置為私有成員變量。 遇到錯誤

member function 'setCost' not viable: 'this' argument has type 'const value_type' (aka 'const Position'), but function is not marked const

我有以下代碼:

class Position {
public:
    Position();
    Position(int x, int y);
    int getCost() const;
    void setCost (int c);
private:
    int x;
    int y;
    int cost;
    };


void Position::setCost (int c){
    this->cost = c;
}

class Board{
public:
    Board();
    Board(int N);
    void shortestPath32 (Position start, Position end);
private:
    int N;
    char W[32][32];
};

void Board::shortestPath32 (Position start, Position end){

  /* some code here */

    set <Position> validMoves = getValidPositions(parent);
    for(auto child =validMoves.begin(); child!=validMoves.end(); ++child ){
        /*some code here ...*/  
        int c = 5
        (*child).setCost(c);

        }

    }
}

顯然,如果我將setCost聲明為void Position::setCost (int c) const ,則無法在內部執行賦值操作。 另外,我調查了此線程的set方法,但沒有幫助。

那是std::set的局限性-它的迭代器總是返回const引用。 理由是-修改集合中的元素可以更改其位置,因此不允許這樣做。

要修改集合中的元素,官方流程是將其從集合中取出,修改並重新插入。

現在,如果您知道修改某些元素的屬性不會影響其位置,那么作為一種骯臟的解決方法,您可以聲明那些mutable和setter的const

class Position {
public:
    Position();
    Position(int x, int y);
    int getCost() const;
    void setCost (int c) const { cost = c; }
private:
    int x;
    int y;
    mutable int cost;
};

一個更骯臟的解決方案是拋棄const ,然后您可以修改任何內容(即使提出來,我也覺得很臟)。

PS通常可以通過選擇更適合您的需求的結構來避免此問題,例如std::map ; 您可以將代碼重構為PositionCost

class Position {
    int x;
    int y;
    . . .
};
class Cost {
    int cost;
    . . .
};

std::map<Position,Cost> validMoves;

這樣您就可以合法地修改Cost ,而Position可以保持const

  for(auto it =validMoves.begin(); it!=validMoves.end(); ++it){
      it->second.setCost(c);
  }

但這是一個設計選擇,可能取決於問題中未提及的其他因素...

根據文檔,集合中元素的值不能一次在容器中修改(元素始終為const),但可以將其插入容器或從容器中刪除。

因此,您需要擦除並重新插入集合中。

如何更新std :: set的現有元素?

正如其他人提到的那樣,您可以拋棄const,但這並不是最好的解決方案,如果這樣做,則必須確保不使用這種開銷。 您可以將set替換為map並將成本存儲在課程之外。

然后,您可以執行以下操作...

void Board::shortestPath32 (Position start, Position end){
  map<Position, int> validMoves; //getValidPositions(parent);    
  for(auto child=validMoves.begin(); child!=validMoves.end(); ++child ){  
    child->second=1; // NYI - replace 1 with the cost    
  }  
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM