Error when compiling: passing (something) as 'this' argument discards qualifiers - c++

I am writing a code and this is a small part of a method i want to implement in a class that inherits from a base class:
const string & getType() const override {
this->type = "Greedy";
return type;
}
and this is the private part of the class:
private:
const string type;
};
Also this is the method im overriding:
virtual const string & getType() const = 0;
when I try to compile the project i get the message:
passing (something) as 'this' argument discards qualifiers
I have seen similar questions but all of them did not have const in the class method that this message was appearing on. Here is a good example of one:
error: passing xxx as 'this' argument of xxx discards qualifiers
Where seems to be the problem?
Thanks

The first problem is that
const string type;
is a const member. That means, after it's initialization you can't assign any new value to it.
The second problem is, that the getter is also marked const:
// VVVVV
const string & getType() const override
Meaning you can't modiy member data from inside this function. Not to mention that it's a bad design if a getter changes a value before returning it.
If this override of getType is suppsed to always return "Greedy" you could do something like this:
const string & getType() const override {
static std::string greedyType = "Greedy";
return greedyType;
}

Related

Unary predicate with member function

I would like to use a unary function to look up a certain parameter name in a list with std::find
class Parameter {
public:
string getName() { return mName;}
//string mName;
private:
string mName;
string mType;
string mValue;
};
class Param_eq : public unary_function<Parameter, bool> {
string mName;
public:
Param_eq (const string& name) : mName(name) {}
bool operator() (const Parameter& par) const {
return (mName == par.getName());
}
};
double Config::getDouble(string& name) {
list<Parameter>::iterator iParam = find(mParamList.begin(), mParamList.end(), Param_eq(name));
double para = iParam->getDouble();
return para;
}
}
But I get the following compiler error
error C2662: 'Parameter::getName' : cannot convert 'this' pointer from 'const Parameter' to 'Parameter &'
Conversion loses qualifiers
If I make the member variable Parameter::mName public and use it instead of the member function Parameter::getName() in the return statement of Param_eq::operator() it compiles without error.
bool operator() (const Parameter& par) const {
return (mName == par.mName);
}
Why is that? Both member variable and member function are string type.
How do I get the above example to work by using a member function?
The error tells you that you are calling a non-const method on a const reference. A non-const method may modify member variables and thus violate the const constraint.
You can solve this two ways:
Don't call the method at all and access the mName variable directly:
bool operator() (const Parameter& par) const {
return (mName == par.mName);
}
Note that this does not require making mName public. This works because operator() is a member of the Parameter class. Remember that private members are accessible in any method of the class. It does not matter whether you access the private members of another instance of the same class or not.
Declare getName() to be const objects:
string getName() const { return mName;}
Note the location of the const qualifier. This tells the compiler that the method will not modify any member variables.

Return pointer to array

I'm trying to return a pointer to an array for my function prototype.
class NAV
{
string date;
float nav;
public:
NAV(const string&);
};
const int HistorySize = 300;
class MutualFund
{
string ticker;
NAV* history[HistorySize];
public:
MutualFund(const string& ticker_, const string& historyFile);
~MutualFund();
NAV** getArray() const{return history;}
void report() const;
};
For NAV** getArray() const{return history;}, I'm getting a compiler error:
error: invalid conversion from 'NAV* const*' to 'NAV**' [-fpermissive]
Any ideas?
In NAV** getArray() const{return history;} const means the programmer promises that calling this function will not cause changes to the state of the MutualFund. By returning a non-const pointer, NAV**, you are opening up the possibility for the state to be changed through use of the returned pointer. The compiler will not allow this and is telling you that it can only return a pointer to constant data: NAV* const*.
Your getter is a const method, so during its execution, all data members are considered const as well. That's why the conversion error says it is converting from const to non-const, since your return value is non-const.

How to fix discards qualifiers [-fpermissive] for cv::SVMParams?

I have a class ConfigFile that has a getter for the SVMParams member:
cv::SVMParams gerSVMParams()
{
return *m_mapConfig["SVMParams"];
}
The code is a little bit more complicated. m_mapConfig is a
std::map<std::string, std::unique_ptr< IConfigItem > >
And IConfigItem is a template class that looks like this for SVMParams:
template<> class ConfigItem< cv::SVMParams > : public IConfigItem
{
private:
cv::SVMParams m_value;
public:
ConfigItem(const cv::SVMParams& valueIn) : m_value(valueIn) {}
operator cv::SVMParams() const
{
return m_value;
}
};
My problem is when I am trying to auto train the SVM classifier:
classifier.train_auto(trainingData, classes, cv::Mat(), cv::Mat(), configFileIn.getSVMParams());
I am getting an error of kind:
error: passing ‘const ConfigFile’ as ‘this’ argument of ‘cv::SVMParams ConfigFile::getSVMParams()’ discards qualifiers [-fpermissive]
Any suggestions of what I am doing wrong? Or is there a small bug because because the train_auto functions has no const in front of the SVMParams parameter. Or is it modifying it?
Make your function const:
cv::SVMParams gerSVMParams() const
// ^^^^^
The error is you are calling a non-const method on a const object, which the compiler rejects as being potentially unsafe. That said, your implementation is inherently non-const too since you might be inserting an object into your map, so just adding the const won't help.
What you probably want to do is:
cv::SVMParams gerSVMParams() const
// ^^^^^
{
auto it = m_mapConfig.find("SVMParams");
if (it != m_mapConfig.end()) {
return *(*it);
}
else {
return {}; // maybe?
}
}
Found the problem: I was calling the function in which I was calling the getSVMParams() with const ConfigFile&; and that was not allowed by the shared_ptr I used in the map.
Thanks all, anyway!

string & reference return type c++?

My uml says that the getter method getName is of type string & and const
(getName(): const string &)
so in my .h file I wrote
public:
std::string & getName() const;
private:
std::string name;
and in my .cpp file
string & Class::getName() const
{
return name;
}
when I try to compile my .cpp file I get an error saying : invalid initialization of reference of type std::string& {aka std::basic_string<char>&} from expression of type const string {aka const std::basic_string<char>}
If I try to change the return value from name to &name, I still get an error. I'm not sure how to fix it. Help please.
You need to return a const reference:
const std::string& getName() const;
Otherwise you are granting non-const access to an object's data via a const method.
When your member function is const, it only has const access to member variables.
So, you cannot bind name to a non-const reference inside that function.
Your return type will have to be const std::string&.

Return a read-only double pointer

I want to a member variable, which is a double pointer. The object, the double pointer points to shall not be modified from outside the class.
My following try yields an
"invalid conversion from ‘std::string**’ to ‘const std::string**’"
class C{
public:
const std::string **getPrivate(){
return myPrivate;
}
private:
std::string **myPrivate;
};
Why is the same construct valid if i use just a simple pointer std::string *myPrivate
What can i do to return a read-only double pointer?
Is it good style to do an explicit cast return (const std::string**) myPrivate?
Try this:
const std::string * const *getPrivate(){
return myPrivate;
}
The trouble with const std::string ** is that it allows the caller to modify one of the pointers, which isn't declared as const. This makes both the pointer and the string class itself const.
If you want to be really picky :
class C {
public:
std::string const* const* const getPrivate(){
return myPrivate;
}
private:
std::string **myPrivate;
};
There are very rare cases in c++ when a raw pointer (even less for a double pointer) is really needed, and your case doesn't seams to be one of them. A proper way would be to return a value or a reference, like this :
class C{
public:
const std::string& getPrivate() const
{
return myPrivate;
}
private:
std::string myPrivate;
};