C++ 设置方法 : function 'setCost' not viable: 'this' argument has type 'const value_type'

标签 c++

我无法通过 set 方法为私有(private)成员变量设置值。获取错误

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,我将无法在其中进行赋值操作。另外,我调查了 this thread对于 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,然后你可以修改任何东西(我什至都​​觉得很肮脏)。

附言通常可以首先通过选择更适合您需求的结构来避免这个问题 - 例如 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);
  }

但这是一个设计选择,可能取决于问题中未提及的其他因素......

关于C++ 设置方法 : function 'setCost' not viable: 'this' argument has type 'const value_type' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41924944/

相关文章:

c++ - 使用QMediaPlayer时出现"QWidget::paintEngine: Should no longer be called"

C++:为什么要在这里调用析构函数?

c++ - 使用 exit(1) 从函数返回

c++ - 在使用 Qt 制作的 GUI 上按下按钮时启动 shell 脚本

C++11 异步 + 然后

c++ - 连接两个十六进制数

c++ - OpenCV - 用于边缘图(不是轮廓)的 approxPolyDP

c++ - 从 C++ 中的基方法调用重写的子方法

javascript - 如何决定 SQLite 文件在 QML LocalStorage 中的存储位置

C++ 包含 header /前向声明顺序