i have a problem to delete an "Member" from a "Group" by index:
#include <vector>
#include <string>
using namespace std;
class Member
{
public:
explicit Member(const string &name, const unsigned long &key) : m_name(name), m_key(key) {}
const string &getName() const {return m_name;};
const unsigned long &getKey() const {return m_key;};
private:
string m_name;
unsigned long m_key;
};
//------------------------------------------------------------------------
class Group
{
public:
explicit Group(const string &name) : m_name(name) {}
const string &getName() const {return m_name;};
void addMember(const Member &member) {m_member.push_back(member);};
const vector<Member> &getMember() const {return m_member;};
private:
string m_name;
vector<Member> m_member;
};
void main() {
vector<Group> group;
group.push_back(Group("Membergroup 1"));
group[0].addMember(Member("Mark", 123456));
group[0].addMember(Member("John", 234567));
group[0].getMember().erase(group[0].getMember().begin() + 1); //to delete John
}
Error: : passing 'const std::vector' as 'this' argument discards qualifiers [-fpermissive] group[_group].getMember().erase(group[_group].getMember().begin() + 1);
Can someone help me please?
The problem is here:
const vector<Member> &getMember() const {return m_member;};
The function getMember() (which I suggest to call as getMembers()) returns a const reference to the vector.
Since constness, the compiler prevents modifications.
You can fix just refactoring in the following way:
class Group
{
public:
// ...
const vector<Member>& getMembers() const { return m_member; }
vector<Member>& getMembers() { return m_member; }
// ...
Related
I'm struggling with the last part of a homework problem and I'm getting the error
error: passing ‘const string {aka const std::__cxx11::basic_string<char>}’ as ‘this’ argument discards qualifiers [-fpermissive]
nm = name_str;
The constructor in question is
Pilot::Pilot(std::string name_str): Aircrew(nm)
{
nm = name_str;
};
with factory function
Aircrew *Aircrew::makeAircrew(char ch, std::string name_str){
if(ch == 'P')
return new Pilot(name_str);
in the header file I have
class Aircrew
{
public:
Aircrew(std::string name_str);
virtual const std::string type(void) const = 0;
virtual const int maxFlights(void) const = 0;
const double maxHours(void) const;
const std::string name(void) const;
void setFlights(int i);
void setHours(double h);
void print(void) const;
virtual void scheduleFlight(int f, double h) const;
static Aircrew* makeAircrew(char ch, std::string name_str);
virtual ~Aircrew(void);
protected:
const std::string nm;
int flightsTaken;
double hoursWorked;
};
class Pilot: public Aircrew
{
public:
Pilot(std::string name_str);
virtual const std::string type(void) const;
virtual const int maxFlights(void) const;
};
Now per the factory function I'm trying to pass a name along to the const nm string but I'm struggling with how to do that. I've been googling to no avail. The goal is to pass name_str to nm so that in the member function name i can do.
const string Aircrew::name(void) const{
return nm;
}
Note: I can't change anything in the header files as per the professor. Thank you in advance!
I've seen other questions on here, but they deal with pointers, or with qobject derived classes, so they didn't seem relevant.
I am trying to append values into a qlist of custom classes, here is the class
class matchPair
{
public:
matchPair(int a=0, int b=0)
: m_a(a)
, m_b(b)
{}
int a() const { return m_a; }
int b() const { return m_b; }
bool operator<(const matchPair &rhs) const { return m_a < rhs.a(); }
// matchPair& operator=(const matchPair& other) const;
private:
int m_a;
int m_b;
};
class videodup
{
public:
videodup(QString vid = "", int m_a = 0, int m_b = 0);
~videodup() {}
QString video;
bool operator==(const QString &str) const { return video == str; }
// videodup& operator=(QString vid, int m_a, int m_b);
QList<matchPair> matches;
};
struct frm
{
QString file;
int position;
cv::Mat descriptors;
QList<videodup> videomatches;
};
QList<frm> frames;
and the line that fails is:
frame.videomatches.at( frame.videomatches.indexOf(vid) ).matches.append(pair);
the error I get is:
/usr/local/Cellar/qt5/5.5.1_2/lib/QtCore.framework/Headers/qlist.h:191: candidate function not viable: 'this' argument has type 'const QList<matchPair>', but method is not marked const
void append(const T &t);
^
what am I doing wrong?
You are trying to append a value to a const QList<T>, which means your QList<T> is constant, i.e. non-mutable. Look closely, the error reads this has type const QList<matchPair>, and you can only call const methods on a const object, while append() obviously is not const both syntactically and semantically. Fix the QList<matchPair> to not be const.
Edit 2:
Having looked closer at the code, here is the culprit, indeed:
frame.videomatches.at( frame.videomatches.indexOf(vid) ).matches.append(pair);
^^
QList<T>::at() returns const T&, which leads to the problem I've described above. Use QList<T>::operator[]() insdead,which has overloads that return both a const T and T values.
Edit:
However, which compiler brand and version is this? I can't reproduce this error message in g++ by calling a non-const method on a const class object, both templated and non-templated (I am getting an error, but it's worded differently).
class cat
{public:
void dog(int ID, char *value) // int ID I'd like to be the index array it was called from?
{
debug(ID, value);
}
}
cat cats[18];
cats[1].dog("value second arg, first arg auto filled from index array");
I want something similar to this.
include <vector>
class CatArray;
class Cat {
// This line means that the CatArray class can
// access the private members of this class.
friend class CatArray;
private:
static int ID;
public:
void dog(const char* value) {
// Use ID here any way you want.
}
};
int Cat::ID = 0;
class CatArray {
private:
std::vector<Cat> cats;
public:
explicit CatArray(unsigned int size) : cats(size) {}
Cat& operator [](unsigned int index) {
Cat::ID = index;
return cats[index];
}
};
But a little different. There are 18 Clients in a game and i need to basically do this. for eg, "Client 4 Chooses an option and the option gets called through the array index and than that way client 4 will call the function with the function holding the index 4"
Then cats[1] is not really a Cat object but a CatWithIndex object:
class Cat {
public:
void dog(size_t index,const char* value);
};
class CatWithIndex {
size_t index_;
const Cat &cat_;
public:
CatWithIndex(size_t index, const Cat &cat): index_(index), cat_(cat) {}
void dog(const char* value) {
cat_.dog(index_,value);
}
};
class CatArray {
private:
std::vector<Cat> cats;
public:
Cat& operator [](unsigned int index) {
Cat::ID = index;
return CatWithIndex(index,cats[index]);
}
};
I've been assigned the following template:
#include <map>
template <typename T>
class Catalog {
struct Item {
//..
};
std::map<int, Item*> items;
public:
Catalog(void);
Catalog(const Catalog&);
~Catalog(void);
bool IsEmpty(void) const;
int Size() const;
void Add(T*);
T* Remove(T*);
T* Find(T*);
typedef void (T::*pFunc) (const T&);
void Inspection(pFunc) const;
};
Next, there is an abstract Product class and three subclasses:
class Product {
protected:
unsigned int _id;
string _name;
public:
Product(const int& id, const string& name) : _id(id), _name(name) {};
virtual void Action(const Product& p) = 0;
virtual int hashCode() {
return _id*100;
};
unsigned int getId(void) const {return _id;};
string getName(void) const {return _name;};
};
class ProductA : public Product {
public:
ProductA(const int& id, const string& name) : Product(id, name) {};
virtual void Action(const Product& p) {
cout << "ahoj" << endl;
};
};
Finally, class ProductsCatalog that handles a Catalog instance:
class ProductsCatalog {
Catalog<Product> catalog;
public:
//..
void CatalogInspection(void) const {
catalog.Inspection(&Product::Action);
}
};
What I have trouble with is the Inspection method:
template <typename T> void Catalog<T>::Inspection(pFunc p) const {
for (std::map<int, Item*>::const_iterator it=items.begin(); it!=items.end(); ++it) {
it->second->Product->*p(*(it->second->Product));
}
};
I am getting the following error:
error C2064: term does not evaluate to a function taking 1 arguments
I've tried everything I could think of, without success. The following works as intended, but is obviously not abstract enough:
it->second->Product->Action(*it->second->Product);
Did you try
(it->second->Product->*p)(*(it->second->Product));
for calling the method?
The thread Calling C++ class methods via a function pointer seems to be related.
My issue is :
I define class (generator) inside of which I define a forward nested structs (topics and it_set).
I make the declaration of this nested class inside the .cpp file.
After this I declare a second class (ImageGenerator) which is an inheritence of generator.
I get an issue when I try inside of the declaration file of ImageGenerator.
Is there anyway to make that possible ?
My codes are these :
<i>
//base.hpp
</i>
class generator{
protected:
struct topics;
struct it_set;
NodeHandle _nh;
cv::Ptr<topics> _topics;
cv::Ptr<it_set> _set;
cv::Mat _data;
public:
generator(ros::NodeHandle&,const std::string&,const std::string&,const std::string&);
virtual ~generator(void);
bool ok(void)const;
protected:
virtual void grab(void) = 0;
};
<i>
// base.cpp
</i>
static void cam_from_sub(const std::string& _subscriber,std::string& _cam){
std::stringstream str;
std::vector<std::string> words;
std::string tmp;
for(std::string::const_iterator it = _subscriber.begin();it != _subscriber.end();it++)
(*it != '/')?(str<<*it):(str<<std::endl);
while(!str.eof()){
str>>tmp;
words.push_back(tmp);
tmp.clear();
}
words.pop_back();
for(std::vector<std::string>::iterator it = words.begin(); it != words.end();it++){
_cam+=*it+std::string("/");
it->clear();
}
words.clear();
_cam+= std::string("camera_info");
}
struct generator::topics{
std::string _publisher;
std::string _subscriber;
std::string _camera_info;
topics(const std::string& _pub,const std::string& _sub,const std::string& _cam):_publisher(_pub),_subscriber(_sub),_camera_info(_cam){}
topics(const std::string &_pub, const std::string &_sub):_publisher(_pub),_subscriber(_sub){cam_from_sub(_subscriber,_camera_info);}
~topics(void){}
};
struct generator::it_set{
image_transport::ImageTransport _it;
image_transport::SubscriberFilter _is;
image_transport::Publisher _pb;
message_filters::Subscriber<sensor_msgs::CameraInfo> _cam_info;
it_set(NodeHandle& _nh,cv::Ptr<generator::topics>& _topics):_it(_nh),_is(_it,_topics->_subscriber,1),_cam_info(_nh,_topics->_camera_info,1){ this->_pb = this->_it.advertise(_topics->_publisher,1);}
};
generator::generator(NodeHandle & nh, const std::string & subscribe, const std::string & publish, const std::string & camera_info):_nh(nh),_topics(new topics(publish,subscribe,camera_info)),_set( new it_set(_nh,_topics)){}
generator::~generator(void){ _set.release(); _topics.release();}
bool generator::ok(void)const{ return this->_nh.ok();}
<i>
// image.hpp
</i>
class ImageGenerator : public generator{
private:
NodeHandle _nh;
static bool _sht;
bool _first_sht;
bool _is_sub;
public:
typedef void(*function_type)(const cv::Mat&,cv::Mat&);
private:
function_type _fun;
virtual void callback(const sensor_msgs::ImageConstPtr&);
virtual void grab(void);
public:
ImageGenerator(const NodeHandle&,const std::string&,const std::string&,const std::string&,function_type);
~ImageGenerator(void);
void operator>>(cv::Mat&);
void operator<<(const cv::Mat&);
};
<i>
// image.cpp
</i>
bool ImageGenerator::_sht = false;
void ImageGenerator::grab(void){
if(!this->_is_sub)
this->_set->_is.registerCallback(boost::bind(&ImageGenerator::callback,this,_1));
ros::CallbackQueue* mloop = ros::getGlobalCallbackQueue();
while(!this->_sht)
mloop->callAvailable(ros::WallDuration(0.1f));
this->_sht = true;
mloop = NULL;
this->_is_sub = true;
}
void ImageGenerator::callback(const sensor_msgs::ImageConstPtr &msg){
cv_bridge::CvImagePtr cv_ptr;
cv_ptr = cv_bridge::toCvCopy(msg);
this->_data = cv_ptr->image;
}
ImageGenerator::ImageGenerator(const NodeHandle & nh, const std::string & subscribe, const std::string & publish, const std::string & camera_info, function_type fun):_nh(nh),base::generator(_nh,subscribe,publish,camera_info),_fun(fun){ this->grab();}
ImageGenerator::~ImageGenerator(void){}
The issue which I want to solve is at
void ImageGenerator::grab(void)
It's :
this->_set->_is.registerCallback(boost::bind(&ImageGenerator::callback,this,_1));
the compiler answer :
error invalid use of incomplete type generator::it_set
The type is incomplete because the compiler hasn't seen the definition of that struct.
If you want to use the structs in subclasses of generator, you need to move their definitions inside the definition of generator in "base.hpp".