[英]c++ error: passing ‘const std::vector<Node>’ as ‘this’ argument discards qualifiers [-fpermissive]
[英]c++ “error:passing 'const std::vector<int>' as 'this' argument discards qualifiers [-fpermissive]”
我正在嘗試使用給定示例來實現此 POMDP 求解器,以解決我的決策問題,並按照存儲庫中的文檔在 header 文件中構建不同的相關類和函數
class SimpleState: public State {
public:
int position;
int context;
int time;
SimpleState();
SimpleState(int _position, int _context, int _time) :
rat_position(_position),
context(_context),
time(_time) {
}
SimpleState(int _state_id);
~SimpleState();
std::string text() const;
};
SimpleState::SimpleState() {
}
class StarMazeProblem : public DSPOMDP,
public MDP {
protected:
std::vector<std::vector<std::vector<State> > > transition_probabilities_; //state, action, [state, weight]
mutable MemoryPool<SimpleState> memory_pool_;
std::vector<SimpleState*> states_;
mutable std::vector<ValuedAction> mdp_policy_;
public:
enum {CENTER = 0, RIGHT = 1, LEFT = 2};
public:
StarMazeProblem();
int NumStates() const;
void ComputeDefaultActions(std::string type) const;
ParticleUpperBound* CreateParticleUpperBound(std::string name = "DEFAULT") const;//?
ScenarioUpperBound* CreateScenarioUpperBound(std::string name = "DEFAULT",
std::string particle_bound_name = "DEFAULT") const;
ScenarioLowerBound* CreateScenarioLowerBound(std::string name = "DEFAULT",
std::string particle_bound_name = "DEFAULT") const;
}
在starmaze.cpp
文件中,相關行是
int StarMazeProblem::NumStates() const {
return CONTEXT * POSITIONS * TIME;
}
void StarMazeProblem::ComputeDefaultActions(string type) const {
cerr << "Default action = " << type << endl;
if (type == "MDP") {
const_cast<StarMazeProblem*>(this)->ComputeOptimalPolicyUsingVI();
int num_states = NumStates();
default_action_.resize(num_states);
double value = 0;
for (int s = 0; s < num_states; s++) {
default_action_[s] = policy_[s].action;
value += policy_[s].value;
}
} else {
cerr << "Unsupported default action type " << type << endl;
exit(0);
}
}
ScenarioLowerBound* StarMazeProblem::CreateScenarioLowerBound(string name,
string particle_bound_name="DEFAULT") const {
const DSPOMDP* model = this;
const StateIndexer* indexer = this;
const StatePolicy* policy = this;
ScenarioLowerBound* bound = NULL;
if (name == "TRIVIAL" ) {
bound = new TrivialParticleLowerBound(this);
} else if (name == "RANDOM") {
bound = new RandomPolicy(this,
CreateParticleLowerBound(particle_bound_name));
} else if (name == "MODE" || name == "DEFAULT") {
ComputeDefaultActions("MDP");
bound = new ModeStatePolicy(model, *indexer, *policy,
CreateParticleLowerBound(particle_bound_name));
} else {
cerr << "Unsupported scenario lower bound: " << name << endl;
exit(1);
}
return bound;
}
在這里,我收到上述代碼的以下錯誤:
src/starmaze.cpp:301:36: error: passing 'const std::vector<int>' as 'this' argument discards qualifiers [-fpermissive]
default_action_.resize(num_states);
^
In file included from /opt/local/include/gcc7/c++/vector:64:0,
from ../../../include/despot/interface/lower_bound.h:4,
from ../../../include/despot/core/builtin_lower_bounds.h:4,
from src/starmaze.h:3,
from src/starmaze.cpp:1:
/opt/local/include/gcc7/c++/bits/stl_vector.h:689:7: note: in call to 'void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]'
resize(size_type __new_size)
^~~~~~
我有基本的 c++ 知識,但由於我遵循了示例,所以我無法弄清楚錯誤的原因。 有什么建議嗎?
我已經多次查看此代碼,但找不到default_action_
聲明為const std::vector<int>
的位置。 這使我假設(基於編譯器識別它的事實)該變量是在父類之一中聲明的: public DSPOMDP, public MDP
。
const vector<int>
這個問題很直接。 您不能更改const std::vector<Ty>
制作const的全部目的是防止程序員更改它。 無論您在此處嘗試做什么,都應考慮將矢量數據復制到新矢量中,並在副本中對其進行更改。
好的,假設您決定做一件淘氣的事,並從 *.h 文件中刪除 const ,無論它在哪里。 您仍然會遇到問題(見下文)
這是如果您從向量中刪除了const
default_action_.resize(num_states);
會導致編譯器對你大喊大叫。 現在的問題是您的方法StarMazeProblem::ComputeDefaultActions()
被指定為const 。 這意味着您不能在該函數/類方法中以任何方式更改您的 class 實例。 您正在做的是通過調用resize()
來修改default_action_向量。 這不可避免地會更改class 實例,這是被禁止的,因為您的方法被聲明為const並且您的default_action_向量被聲明在 class 層次結構中的某處。 此外,您通過將向量分配給右值來直接更改向量(參見下面的代碼)
int num_states = NumStates();
default_action_.resize(num_states); // <---- default_action_ cannot be modified
for (int s = 0; s < num_states; s++) {
default_action_[s] = policy_[s].action; // <---- default_action_ cannot be modified
value += policy_[s].value;
}
您需要一份您嘗試修改的向量的副本。 在 100% 不知道自己在做什么的情況下進入h文件並更改它們永遠不是答案。 在 class 方法中制作一個臨時向量,將數據復制到它,並操作復制是完全允許的,不會給您任何編譯器錯誤; 但是,這種方法可能會完全避免您的官方目標。 看起來您確實在嘗試更改default_action_向量,而這似乎是您的真正目標。
我很難就這個特定主題給你一個明確的答案。 主要是因為我不知道整個 class 層次結構是做什么的,也不知道它的確切用途(我簡要查看了提供的鏈接中的代碼。)
您最終需要做的是確定為什么要嘗試更改該向量,以及為什么原始開發人員將其設為const 。 然后,您可以確定除了顯式刪除向量的常量之外是否有更好的方法。
如果您仍在嘗試更改 class 實例,請閱讀下文
此解決方案部分與您正在處理的 class 的限定符有關。
如果絕對有必要從該方法中更改 class 實例,您可以從 class 方法中刪除常量限定符。
或者
為您嘗試做的事情找到一種替代方法,並將其分解為 class 實例上的多個方法調用。
您已經取得了ComputeDefaultActions()
const
-qualified,但很少有人說它應該是。
ComputeOptimalPolicyUsingVI()
,它不是const
限定的,因為它改變了*this
的內部 state 。 您已經通過丟棄const
解決了this
- 但是 function 將 s policy_
resize
為NumStates()
也很大, ComputeDefaultActions()
依賴於它 - 否則內部循環將非常危險。resize
和分配其元素來更改default_action_
。 這可能是一個錯誤,如果所做的計算實際上是為了不改變*this
但是......(見下一個項目符號)*this
的內部 state 。 計算value
只是在計算結束時丟棄,甚至在 function 內部都沒有使用。 要么使 function return value
,要么完全刪除value
。建議更改:
#include <algorithm>
#include <stdexcept>
void StarMazeProblem::ComputeDefaultActions(string type) { // non-const
cerr << "Default action = " << type << endl;
if (type == "MDP") {
ComputeOptimalPolicyUsingVI(); // no casting needed
default_action_.resize(policy_.size()); // dependency made clear
// Use the standard transform function:
std::transform(policy_.begin(), policy_.end(), default_action_.begin(),
[](const auto& p) { return p.action; });
} else {
// friendlier than exit():
throw std::runtime_error("Unsupported default action type " + type);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.