I have a class similar to this one:
struct orden
{
long long time;
double price;
const char* time1;
orden(const char* t, double p) : time1(t),price(p){};
void convertToMs()
{
time = dateToMs2(time1);
}
};
The what I'm doing is to read a file in serial, execute the constuctor of the struct and save the generated object in a vector of orden:
vector<orden> ord;
ifstream fe(filename)
while(getline(fe,order_line))
{
price = stod(order_line.substr(position+2));
time = order_line.substr(0,26).c_str();
ord.push_back(time, price);
}
Then, what I want to do in parallel is to execute the member function convertToMs(). But I have problems because the compiler ask me to execut only constant functions inside parallel for.
I have tryed some thinks that I have found like this one Without sucess because they are not saving the result of the execution in a parameter of the object.
What I'm doing wrong?
Thank you in advance
EDIT:
If I use
struct orden
{
long long time;
double price;
const char* time1;
orden(const char* t, double p) : time1(t),price(p){};
void convertToMs() const
{
time = dateToMs2(time1);
}
};
I have the following error:
In file included from pract1.cpp:5:0:
orden.h: In member function ‘void orden::convertToMs() const’:
orden.h:29:27: error: assignment of member ‘orden::time’ in read-only object
time = dateToMs2(time1);
If I delete the const i have the following one:
pract1.cpp: In lambda function:
pract1.cpp:158:43: error: passing ‘const value_type {aka const orden}’ as ‘this’ argument discards qualifiers [-fpermissive]
ordersOfTheCompany[j].convertToMs();
^
In file included from pract1.cpp:5:0:
orden.h:27:8: note: in call to ‘void orden::convertToMs()’
void convertToMs()
EDIT 2:
Sorry again, i have the folloging code:
vector<orden> ord;
while(getline(fe,order_line))
{
price = stod(order_line.substr(position+2));
time = order_line.substr(0,26).c_str();
ord.push_back(time, price);
}
tbb::parallel_for(tbb::blocked_range<size_t>(0,ord.size()),
[=](tbb::blocked_range<size_t>& r) {
for(std::size_t j=r.begin(); j!=r.end(); ++j)
{
ord[j].convertToMs();
}});
I'm trying to execute the member function in a parallel for
The documentation for parallel_for has an example similar to what you're trying to do. It saves the result into a separate array from the input array.
In your case, you'd want to add something like
std::vector<long long> outTime;
outTime.resize(ord.size());
right before the parallel_for call. Then, in the body of the lambda you execute, change the statement to
outTime[j] = ord[j].convertToMs();
after changing convertToMs to be a const function that returns the converted value rather than saving it locally. After the parallel_for returns, copy the results out of outTime back into ord.
You could have 2 versions of convertToMs, a non-const one that saves the result internally, and a const one that returns the converted time.
Related
I am trying to implement this POMDP solver with given examples for my decision making problem and I followed the documentation in the repository to build different relevant classes and functions in the header file
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;
}
and in the starmaze.cpp file the relevant lines are
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;
}
here I got the following error for the above code:
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)
^~~~~~
I have basic c++ knowledge and I could not figure out the reason for the error since I followed the examples. Any suggestion?
Important to know before reading
I've looked over this code several times, and cannot find where default_action_ is declared as a const std::vector<int>. This leads me to assume (based on the fact that the compiler recognizes it as such) that the variable is declared in one of the parent classes: public DSPOMDP, public MDP.
You are trying to modify a const vector<int>
This issue is pretty straight-forward.
You cannot change a const std::vector<Ty>
The whole point of making something const is to prevent the programmer from changing it.
Whatever you are trying to do here, you should consider copying the vector data into a new vector, and make the changes to it in the copy.
Okay so let's say you decided to do the naughty deed and remove const from the *.h file wherever it may be. You'll still have an issue (see below)
You are trying to modify the class instance from a const method
This is if you removed const from the vector
The default_action_.resize(num_states); is going to cause the compiler to yell at you.
The issue here is now your method StarMazeProblem::ComputeDefaultActions() is specified as const. This means you cannot change your class instance in any way from within that function/class method. What you are doing is modifying the default_action_ vector by calling resize() on it. This inevitably changes the class instance which is forbidden because your method is declared const and your default_action_ vector is declared somewhere in your class hierarchy. Additionally you are changing the vector directly by assigning it to an rvalue (See code below)
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;
}
Solution
You need a copy of the vector you are trying to modify. Going into h files and changing them without knowing 100% exactly what you are doing is never the answer.
Making a temporary vector in the class method, copying the data to it, and manipulating the copy is completely allowed and will not give you any compiler errors; however, this approach may completely avoid your official goal. It looks like you are really trying to change the default_action_ vector and that almost seems like your true goal here.
It's hard for me to give you a definitive answer on this specific topic. Mainly because I do not know what this entire class hierarchy does or what it is for exactly (I briefly looked over the code in the link provided.)
What you'll need to do ultimately is determine why you are trying to change that vector, and why it was made const by the original developers. Then you can determine if there is a better way other than explicitly removing the constness of the vector.
If you are still trying to make changes to the class instance read below
This solution part has to do with the qualifier of the class you are dealing with.
You can either remove the constant qualifier from the class method if it is absolutely necessary to make changes to the class instance from within that method.
OR
Find an alternative method for what you are trying to do, and break it up into multiple method calls on the class instance.
You've made ComputeDefaultActions() const-qualified, but there is very little that says that it should be.
It calls ComputeOptimalPolicyUsingVI() which is not const-qualified since it changes the internal state of *this. You've worked around that by casting away const on this - but that function resizes policy_ to also be NumStates() big which ComputeDefaultActions() depends on - otherwise the internal loop would be very dangerous.
It changes default_action_ by resizeing it and by assigning its elements. This may be a mistake, if the computation made is actually meant to not change *this but ... (see next bullet)
It doesn't return anything. Everything the function does is to change the internal state of *this. The computed value is just dropped at the end of the calculation and it's not even used internally in the function. Either make the function return value or remove value completely.
Suggested changes:
#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);
}
}
a simple and I guess easy to answer question (if I did not already got it myself). The following overloaded functions:
void BR(const bool set) { backwardReaction_[nReac_] = set; }
bool BR(const int reactionNumber) const { return backwardReaction_[reactionNumber]; }
The first function is a setter and the second a getter function. backwardReaction_ is of type std::vector<bool>. The problem occurs whenever I want to call the second function. Here I get a compiler error overload function BR(xy) ambigious.
int main()
.
.
const int i = 3;
bool a = chem.BR(i);
The compiler error is equal to:
chemistryTestProg.cpp: In function ‘int main()’:
chemistryTestProg.cpp:74:34: error: call of overloaded ‘BR(const int&)’ is ambiguous
const bool a = chem.BR(i);
^
In file included from ../../src/gcc/lnInclude/chemistryCalc.hpp:38:0,
from ../../src/gcc/lnInclude/chemistry.hpp:38,
from chemistryTestProg.cpp:35:
../../src/gcc/lnInclude/chemistryData.hpp:266:18: note: candidate: void AFC::ChemistryData::BR(bool)
void BR(const bool);
^~
../../src/gcc/lnInclude/chemistryData.hpp:322:22: note: candidate: bool AFC::ChemistryData::BR(int) const
bool BR(const int) const;
^~
I guess that I get the problem because of the types bool and int which are identically (true => int(1), false => int(0). As I am changing the getter name to, e.g., bool getBR(const int reactionNumber) {...} everything works fine. So I guess the problem is about the similarities of the bool and int treatment within c++. I also tried a variety of different calls such as:
const bool a = chem.BR(4)
const bool a = chem.BR(int(5))
const bool a = chem.BR(static_cast<const int>(2))
bool a = chem.BR(...)
Thus, I think it is really related to the bool andint overloading arguments. Nevertheless, I made a quick search and did not find too much about these two overload types and resulting problems. Tobi
This is because you declared BR(int), but not BR(bool), to be const. Then when you call BR(int) on a non-const object, the compiler has two conflicting matching rules: parameter matching favours BR(int), but const-ness matching favours BR(bool).
Consider the following function:
template <int node>
void RemainingEnergyTrace (double oldValue, double newValue)
{
std::stringstream ss;
ss << "Energy_" << node << ".log";
static std::fstream f (ss.str().c_str(), std::ios::out);
f << Simulator::Now().GetSeconds() << " Remaining energy=" << newValue << std::endl;
}
Note the template definition of the function int node. I try to pass the address of this function in main():
int inc = 0;
eSources.Get (inc)->TraceConnectWithoutContext ("RemainingEnergy", MakeCallback(&RemainingEnergyTrace<inc>));
which generates the following errors:
error: the value of ‘inc’ is not usable in a constant expression
eSources.Get (inc)->TraceConnectWithoutContext ("RemainingEnergy", MakeCallback(&RemainingEnergyTrace<inc>));
^
error: no matching function for call to ‘MakeCallback(<unresolved overloaded function type>)’
eSources.Get (inc)->TraceConnectWithoutContext ("RemainingEnergy", MakeCallback(&RemainingEnergyTrace<inc>));
^
However, the following statement works:
eSources.Get (0)->TraceConnectWithoutContext ("RemainingEnergy", MakeCallback(&RemainingEnergyTrace<0>));
In summary, an actual number works, but when an integer variable is passed in the template format, it does not. Is it because the integer variable has to be of const type (as suggested by the error)?
I am trying to actually run a loop and pass the address of the function for different integer values. How can I make this work?
for(int inc = 0; inc<nWifi; inc++)
{
eSources.Get (inc)->TraceConnectWithoutContext ("RemainingEnergy", MakeCallback(&RemainingEnergyTrace<inc>));
}
In short, you can't. Since templates are expanded at compilation time, you need to provide the values at compilation time as well. If nWifi is a value that's only available at runtime, you need to use a regular parameter:
void RemainingEnergyTrace (double oldValue, double newValue, int node);
If you want then to create partially applied functions to pass to your MakeCallback, you can create them using lambdas:
for(int inc = 0; inc<nWifi; inc++)
{
auto callback = [=](double oldVal, double newVal) {
RemainingEnergyTrace(oldVal, newVal, inc);
};
...
}
But this won't decay to a function pointer, so you might need to change your MakeCallback API to e.g. use std::function (which is a preferred method nowadays) or to take an additional parameter1, or alternatively use some library that will provide the delegate functionality you need.
1Typically, a C or C++ API that takes function pointers would also take an additional void* parameter to store alongside the function pointer. Then, when calling, the pointer would be passed to that function, and store the necessary closure data (in your case, it could point to the inc value residing somewhere in memory). Without knowing how the MakeCallback works, it's impossible to tell what would be the best solution here.
I setup a class called tagToken.
It has setter functions, one is void setString(QString)
I have it defined/declared as such
.h file
void setString(QString string);
Private:
QString stringOfTagToken ;
.cpp file
void tagToken::setString(QString string)
{
stringOfTagToken = string;
}
When I try to run this code:
if (linePosition == 1)
{
QVector<tagToken> temp(0);
//errors
//temp.at(0).setString(line);
temp.at(0).setString("test");
//tags.at(0).setString(line);
//tags.push_back();
tagTokenCounter++;
}
I get this error:
C:\Dev\DiffMatchPatch\diffmatchpatch.cpp:316: error: passing 'const tagToken' as 'this' argument of 'void tagToken::setString(QString)' discards qualifiers [-fpermissive]
temp.at(0).setString("test");
QVector's at function returns data as const. Use at when you don't want to (accidentally) change the vector data, or operator[] in general.
temp[0].setString("test");
QVector::at() returns a const ref to your data, you cannot call a non-const method like setString on that
From http://qt-project.org/doc/qt-4.8/qvector.html#at
const T & QVector::at ( int i ) const
Returns the item at index position i in the vector.
i must be a valid index position in the vector (i.e., 0 <= i < size()).
Consider using operator[] instead
So I've got
set<MyClass> mySet;
and in MyClass I have a static int to count the number of compares that happen. I'm trying to get that information out of it but I can't figure out how.
This is what I've tried:
set<MyClass>::iterator it = mySet.begin();
int count = it->getCompareCount();
and
int count = mySet.begin()->getCompareCount();
Neither of those work (Yes I know the are essentially the same exact thing) but I can get that information out of something that is indexed like a std::list or std::vector
Example:
vector<MyClass> myVector;
for (int i = 0; i < 10; i ++)
{
myVector.push_back(MyClass(i,"Some Name", i*2);
}
int count = myVector.at(2).getCompareCount(); //which by default is going to be 0 as no compares have taken place
Can anybody help me? netbeans says "error: passing ‘const MyClass’ as ‘this’ argument of ‘int MyClass::getCompareCount()’ discards qualifiers [-fpermissive]" when I do what I said I tried up above.
EDITS
Declaration of getCompareCount():
int MyClass::getCompareCount()
{
return compareCount;
}
Element in std::set is not mutable after it is inserted into the set. When you dereference an iterator (as in it->), it returns a const reference of the object you put into the set. On the other hand, your definition of getCompareCount() is a non-const instance function meaning it can only be called on non-const instance of the class. Define the function as the following should solve your problem.
int MyClass::getCompareCount() const
{
return compareCount;
}
By the way, since compareCount is a static int, you might want to define the function as static as well so that you can call it using the class instead of having to get an instance to call it.
static int MyClass::getCompareCount()
{
return compareCount;
}
//To Call it
MyClass::getCompareCount()