CPOI and CWaypoint - c++

I have used operator overloading for +=operator like this
CRoute& CRoute::operator+=(string name ){
CWaypoint *p=this->m_pWpDatabase->getPointerToWp(name);
if(p!=NULL){
this->addWaypoint(name);
}
else{
cout<<" Waypoint not found in DB "<<endl;
}
return *this;
}
Now i want to do same operation += to add poi to my route,i am using the syntax
CRoute& operator+=(string namepoi);
but i am getting error message as 'CRoute& CRoute::operator+=(std::string)' cannot be overloaded
Can someone help??

Function signature of your suggested operator overloaded function is conflicting with the one existing currently. So if you would like to create operator overloading for poi why can't you pass the poi object instead its name?

Related

Error C2679 binary '<<': no operator found which takes a right-hand operand of type 'T'

I try to compile the following code:
class CFileOperations
{
...
template <typename T>
inline void load_and_save_data(std::fstream* stream, T& value, const EOperation operation)
{
switch (operation) {
case EOperation::OpSave:
*stream << value; <-- here
break;
case EOperation::OpLoad:
*stream >> value; <-- and here
break;
}
}
...
};
I get the following errors:
Error C2679 binary '<<': no operator found which takes a right-hand operand of type 'T' (or there is no acceptable conversion)
Error C2679 binary '>>': no operator found which takes a right-hand operand of type 'T' (or there is no acceptable conversion)
For example, I use it this way, with number being an 'int':
this->load_and_save_data(stream, number, operation);
I'm using Visual C++ 2019.
What's the root cause, and how to solve it. Any idea ?
My bad, one of the calls was with a 'class enum'. Of course, >> and << are not defined for it.
For #cdhowie, here are two examples of the resulting simplicity (with the help of load_and_save_data template methods):
Here mMembers is a std::unorderedmap (cf. save_and_load_data in the question above, I have also one for the starndard containers):
void CHexArea::load_and_save()
{
this->load_and_save_data((char&)mColor);
this->load_and_save_data(mTouchLeft);
this->load_and_save_data(mTouchRight);
this->load_and_save_data(mTouchBottom);
this->load_and_save_data(mTouchTop);
this->load_and_save_data(mMembers);
}
Here, in preferences, there are two versions of files:
void CHexPreferences::load_and_save()
{
if( this->is_loading() ) {
this->reset(); // version's forward compatibility
}
int version = 2;
this->load_and_save_data(version);
this->load_and_save_data(mBoardOrientation);
this->load_and_save_data(mBoardSize);
this->load_and_save_data(mComputerStarts);
this->load_and_save_data(mComputerInitialTurns);
if( version >= 2) {
this->load_and_save_data(mComputerTilesPerTurn);
}
this->load_and_save_data(mDebugFlags);
}
Simple and clear.
Of course, there are two methods (load() and save()) that are the outer interface and calls those here above, but: 1. They are part of a library (no need to rewrite them, OO as usual) and 2. The core of the load/save is written only once in load_save_data, with the advantage of simplicity, and having corresponding load and save code (types, order...).
Of course, there are cons, but I hope you'll see that it may make sense for some people to think that there are (IMHO very strong) pros as well.
The rest is a matter of taste.

Overloaded operator has too many parameters, visual studio c++

I'm trying to declare an overload, non-friend, non-member ' - - operator in a header file:
Quad operator-(const Quad &qu1, const Quad &qu2);
But I am getting:
"error C2804: binary 'operator -' has too many parameters"
This code is right from the book and problem statement and I cannot seem to resolve it. Thanks for your help.
Binary operators in class definition scope must take only one argument.
Quad operator-(const Quad &quRight)
{
Quad res;
res.x = this->x - quRight.x;
// all other components
// ...
return res;
}
Or you can move operator overloading outside of class.

Overloaded methods - (Error C2664: Cannot convert from vector<T> to T)

I'm trying to call an overloaded method from the other overloaded member. I am getting an error C2664: Cannot convert argument 2 from std::vector<PK_BODY_T*, std::allocator<_Other>> to PK_BODY_T
Code:
std::vector<PK_BODY_t*> FillHoles(std::vector<std::vector<PK_EDGE_t>> holes, PK_BODY_t inputBody)
{
std::vector<PK_BODY_t*> vectorBodies;
PK_BODY_t *pointerInputBody = new PK_BODY_t(inputBody);
vectorBodies.push_back(pointerInputBody);
std::vector<PK_BODY_t*> returnVector;
returnVector = FillHoles(holes, vectorBodies); //<-- ERROR HERE. Calling overloaded method.
delete pointerInputBody;
return returnVector;
}
/* overloaded version of FillHoles
*/
std::vector<PK_BODY_t*> FillHoles(std::vector<std::vector<PK_EDGE_t>> holes, std::vector<PK_BODY_t*> inputBody)
{
//...
std::vector<PK_BODY_t*> fillHoleOutput = FillOneHole(currentBody, currentHole);
return fillHoleOutput;
}
It appears as if the first method is trying to call itself here, instead of the second overloaded method. How do I force it to use the second method?
You did not show how the functions are declared and in what scopes whether one function hides other function.
But in any case just declare the second overloaded function inside the first overloaded function
std::vector<PK_BODY_t*> FillHoles(std::vector<std::vector<PK_EDGE_t>> holes, PK_BODY_t inputBody)
{
std::vector<PK_BODY_t*> FillHoles(std::vector<std::vector<PK_EDGE_t>> holes, std::vector<PK_BODY_t*> inputBody);
//...
C++ files are compiled from top to bottom. From the vantage point of the top method, it cannot 'see' the second method, because it has not been compiled yet (as the second method is after the first method).
You must either declare methods in a header .h file, or forward declare the methods at the top of the .cpp file.
http://www.learncpp.com/cpp-tutorial/19-header-files/
http://www.learncpp.com/cpp-tutorial/17-forward-declarations/

all_of asking for argument list

After using all_of succesfully once I tried to do it again.
if (all_of(Enemies.begin(), Enemies.end(), in_lock_range))
{
lock_on = -1;
}
The vector is:
std::vector<Enemy> Enemies;
The function is:
bool Player::in_lock_range(Enemy arg)
{
if (get_distance(mouseTarget.x, mouseTarget.y, arg.x, arg.y) > arg.erect.r) return true;
else return false;
}
get_distance(x1,x2,y1,y2) returns the distance from 2 points
Enemy is a friend class to Player and vice versa so they use each other's stuff freely.
The error I recieve is
error C3867: 'Player::in_lock_range': function call missing argument list; use '&Player::in_lock_range' to create a pointer to member
I'm not sure why he is apparently asing for agruments for in_lock_range when I don't believe it needs any when in all_of, as I have used it in a different situation with no such issue.
Can anyone please explain to me what the cause of this can be? I am not really experienced in this. Thanks.
It's a member function, so the syntax for taking a pointer is
&Player::in_lock_range
This is only usable if it's a static member, since it must be callable with just a single argument. I'm guessing it isn't - presumably mouseTarget is a non-static data member of Player. In that case, you'll have to bind it to some player object:
bind(&Player::in_lock_range, std::ref(some_player), std::placeholders::_1)
or wrap it in a lambda:
[&](const Enemy& e){return some_player.in_lock_range(e);}
The function should probably take its argument by constant reference rather than value; and you might want to simplify the return statements
if (whatever) return true;
else return false;
to the more readable
return whatever;

Replacing a set object with a new set object

I have a class with a private field:
std::set<std::string> _channelNames;
.. and an optional setter function:
void setChannelNames(std::set channelNames);
In the setter function, how do I replace the private _channelNames field with the one passed from the setter function?
I tried:
void Parser::setChannelNames(std::set channelNames) {
this->_channelNames = channelNames;
}
But this produced an error in VS2005:
Error 2 error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::set' (or there is no acceptable conversion) parser.cpp 61
I am definitely a C++ novice, and expect that I should be doing some pointer work here instead.
Any quick tips?
Thanks!
You just have to specialize template. You cannot use std::set without specialization.
void Parser::setChannelNames(const std::set<std::string> & channelNames) {
this->_channelNames = channelNames;
}