comparing c++ string - c++

class Song {
public:
const string getAutherName();
}
void mtm::RadioManager::addSong(const Song& song,const Song& song1) {
if (song.getAutherName() == song1.getAutherName())
}
I get this error:
Invalid arguments ' Candidates are: std::basic_string<char,std::char_traits<char>,std::allocator<char>> getAutherName() ' - passing 'const mtm::Song' as 'this' argument of 'std::string mtm::Song::getAutherName()' discards qualifiers [- fpermissive]
Why is it using basic_string and not string! how to fix this?

Your getAutherName() function is not const, so it cannot be called through a const Song&. Change the function declaration like this:
class Song {
public:
const string getAutherName() const;
}

You are calling getAutherName() on const Songs so you need to make that method const:
const string getAutherName() const;
It isn't clear why you return a const string. Either return a string, or return a const reference to one:
const string& getAutherName() const;
string getAutherName() const;

std::string is a typedef for basic_string<char, std::char_traits<char>, std::allocator<char> >, the compiler is just expanding the typedef in the error message.
However, why the code is not working I don't know. You appear to have cut out part of your error message where the ' is.

You need to add a const qualification to getAutherName to allow it to be called on const Song objects:
//| -- Returns a `const` `string` (this is bad practice
//v because it inhibits optimization)
const string getAutherName() const;
// Can be called on a `const` ^
// `Song`. This is good practice |
// because it it allows `getAutherName()`
// to be used in more places, and it encourages
// const-correctness.

Related

Not able to compare string references from function returning references

Visual Studio Version 16.10.3, C++17, Win10-64.
I can't figure this one out. I think I've got all the buzzwords correct but I get errors for the following code:
#include <string>
using namespace std;
class AssetID {
private:
string& asset_Name;
public:
const string& getName() { return asset_Name; }
}; // class AssetID
static
bool compareName(const AssetID* lhs, const AssetID* rhs) {
return lhs->getName() < rhs->getName();
};
Code Description Project File Line Suppression State
C2662 'const std::string &AssetID::getName(void)': cannot convert 'this' pointer from 'const AssetID' to 'AssetID &' HOAAnalysis DTest.h 15
C2662 'const std::string &AssetID::getName(void)': cannot convert 'this' pointer from 'const AssetID' to 'AssetID &' HOAAnalysis Test.h 15
const AssetID* lhs
This is a pointer to a const object. Derefencing it gives you a const object. When you have a const object you can only call its const methods.
const string& getName() { return asset_Name; }
This is not a const method. It is a method that returns a reference to a const object, which is not the same thing. This should be:
const string& getName() const { return asset_Name; }
And now you have a const class method.

Passing ‘const ...’ as ‘this’ argument discards qualifiers

I'm stuck. When trying to add a new element to the vector of strings inside a struct via the iterator I get this error about const qualifier:
error: passing ‘const std::vector<std::__cxx11::basic_string<char> >’ as ‘this’ argument discards qualifiers [-fpermissive]
175 | p->children.push_back("New child");
The code:
typedef struct Concept_tree
{
string id;
string name;
std::vector<string> children;
bool operator==(const Concept_tree &ct2)
{
return (id == ct2.id);
}
Concept_tree() { };
Concept_tree(string id): id(id) { };
Concept_tree(string id, string term): id(id), name(term) { };
}
Concept_tree;
namespace std
{
template<>
struct hash<Concept_tree>
{
size_t operator()(const Concept_tree &ct) const
{
return std::hash<string>()(ct.id);
}
};
}
...
std::unordered_set<Concept_tree> ct_uset;
...
string test = "id00001";
auto p = ct_uset.find(test);
p->children.push_back("New child");
I understand the cause of the error but can't deduce its exact position. Is it that the constructors are implemented improperly? Could anyone help?
You got the iterator p from an unordered_set; the contents of unordered_set are immutable (to avoid violating invariants), and the iterator returned is a const view of the elements to ensure that.
You could mark children as mutable so it can be mutated even when the Concept_tree is const (since it's not part of equality/hash computation, this might be okay). But this will make it possible to mutate children even when you want a Concept_tree to be logically const. To avoid that, you could use an unordered_map mapping just the id (immutable key) to the actual Concept_tree (mutable value) object.
Side-note: You probably want to mark your operator== as const so this is const, or make it a non-member function with both argument const per What are the basic rules and idioms for operator overloading?.

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

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;
}

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.

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&.