簡體   English   中英

c++“錯誤:傳遞'const std::vector<int> ' 因為 'this' 參數丟棄了限定符 [-fpermissive]”</int>

[英]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方法修改 class 實例

這是如果您從向量中刪除了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_ resizeNumStates()也很大, ComputeDefaultActions()依賴於它 - 否則內部循環將非常危險。
  • 它通過resize和分配其元素來更改default_action_ 可能是一個錯誤,如果所做的計算實際上是為了不改變*this但是......(見下一個項目符號)
  • 它不返回任何東西。 function 所做的一切就是改變*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.

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