How do I create a function with multiple identifiers? - c++

I want to make a function, and in different contexts it is better called by different names.
class box(){
private:
float posX;
float size = 10;
public:
float speedX;
float left(){ return posX; } //Any way to combine these?
float posX(){ return posX; } //Any way to combine these?
float right(){ return posX + size; }
};
box a;
box b;
bool checkCollide(){
if(a.right() < b.left()){ return 0; } //Not colliding
if(b.right() < a.left()){ return 0; } //Not colliding
return 1; //Colliding
} //Comparing right and left makes more sense than anything else
void physics(){
a.posX() += a.speedX;
b.posX() += b.speedX;
//Adding speed to position makes more sense than
//adding speed to "left"
}
//Loop physics X times per second, and do something if there's a collision
or, is there a better way to do this? Can I make the left/right member automatically update any time the position or size changes, instead of recalculating for every call?

If you are really obliged to do this, then just make the one function call the other:
// the function that does the hard job
float foo(float a, float b)
{
// some heavy and complicated code
// ...
// some more black magic, etc.
// finally:
return sqrt(a * a + b * b);
}
// the function that pretends to do the hard job
float bar(float a, float b)
{
return foo(a, b);
}
But you better not do this, it's quite bad style. Different names => different tasks. Same task => same name. Don't hurt the intuition of your fellows... ;-)

Yes - Not write two functions that at the start do the same thing. I just hope that they do not diverge. Then you have problems!

If you're on C++11, or when using Boost, you can bind the left() function to an std::function variable. With C++11:
class box {
// ...
public:
// ...
float left() { return posX; }
const std::function<float()> posx = std::bind(&box::left, this);
The const is needed, otherwise posx could be changed at runtime to point to a different function.
If you're not using a C++11 compiler but use Boost instead, then it's not that expressive, since you have to initialize posx in the ctor:
class box {
// ...
public:
box() : posx = boost::bind(&box::left, this);
// ...
float left() { return posX; }
const boost::function<float()> posx;
In both cases, you can now do:
box b;
b.left();
b.posx();
This method doesn't really have any advantages I can think of compared to having a posx() function and calling left() in it. But it's possible and so deserves a mention.
But I agree with what H2CO3 said: don't have two names for the same function. It's confusing.

Related

forward_list iterators incompatible

I'm trying to complete a program that evaluates polynomials when given an x-value.
The polynomials are stored using the STL's forward_list in objects of the class.
class PolyTerm {
private:
int _order = 0;
double _coeff = 0.0;
public:
PolyTerm() = default;
PolyTerm(int order, double coefficient) : _order(order), _coeff(coefficient) {}
void setOrder(int order) { _order = order; }
void setCoeff(double coeff) { _coeff = coeff; }
int getOrder() const { return _order; }
double getCoeff() const { return _coeff; }
};
My function which takes the object and the x-value is written as follows:
double evaluate(const forward_list<PolyTerm>& terms, double x) {
double answer = 0;
forward_list<PolyTerm>::iterator it;
while (it != terms.end()) {
answer += it->getCoeff() * pow(x, it->getOrder());
it++;
}
return answer;
}
My compiler doesn't show any errors but once I try to run the program, I get a pop-up saying "Debug Assertion Failed!" with Expression: forward_list iterators incompatible
Image of pop-up
I'm pretty sure I declared the iterator to be of the same type as the list holding the polynomial so I'm not sure why I'm getting this error.
Can anyone explain to me what's wrong?
Thanks in advance for any help.
forward_list<PolyTerm>::iterator it; it's not initialized. It must be initialized with the first element of the forward list.
forward_list<PolyTerm>::iterator it = terms.begin();
You may simplify you loop, and you will not use it
for (const auto& term : terms)
answer += term.getCoeff() * pow(x, term.getOrder());
You also could have used std::accumulate, as that will enforce the initialization using the third argument to the function. Also, since there is no need to declare and initialize iterators, there is no chance you will forget to initialize the iterator.
Here is an example. Note that there are no hand-written loops:
#include <numeric>
//...
double evaluate(const forward_list<PolyTerm>& terms, double x)
{
return std::accumulate(terms.begin(), terms.end(), 0.0, // <-- Note the initial value is 0.0 -- you can't miss it
[&](double total, const PolyTerm& p)
{ return total + p.getCoeff() * pow(x, p.getOrder()); });
}
You never initialize it.
You should have used a for loop.
You should have used a C++11 for(auto it: terms) as I think it would go.

Using function object in stl algorithm

When trying to use a conditional copy_if algorithm to copy only the values that are lower than mean of values in a vector into another vector, I hit a snag with my function object:
struct Lower_than_mean
{
private:
double mean;
vector<double>d1;
public:
Lower_than_mean(vector<double>a)
:d1{a}
{
double sum = accumulate(d1.begin(), d1.end(), 0.0);
mean = sum / (d1.size());
}
bool operator()(double& x)
{
return x < mean;
}
};
int main()
{
vector<double>vd{ 3.4,5.6, 7, 3,4,5.6,9,2 };
vector<double>vd2(vd.size());
copy_if(vd.begin(), vd.end(), vd2, Lower_than_mean(vd));
}
What is the right way of going about this?
You used vd instead of vd.begin() in the call to std::copy_if.
But, seriously, you didn't bother to even read your compiler output...
Also, like #zch suggests - your approach doesn't make sense: Don't keep re-calculating the mean again and again. Instead, calculate it once, and then your function becomes as simple [mean](double x) { return x < mean; } lambda.

Mutable vs Lazy Evaluation

Recently I was reading this faq on const-correctness. Now I came across the following situation where I dont know what to make const or mutable.
Assume the simple example:
class Averager {
public:
Averager() : sum(0),isUptoDate(false),N(0){}
void add(double x){
sum+=x;
N+=1;
isUptoDate = false;
}
double getAverage() const {
if (!isUptoDate){updateAverage();}
return average;
}
private:
void updateAverage(){
if(N>0){average = sum / N;}
else {average = 0;}
isUptoDate = true;
}
double sum;
mutable bool isUptoDate;
int N;
double average;
};
In the real case, updateAverage() is an expensive calculation, thus I want to avoid updating each time a value is added. Also, getAverage() might be called several times, before a new value is added, thus I want to update only if really necessary. On the other hand, it should not be the responsibility of the user of the class to call updateAverage(), thus I used the flag to know whether an update has to be made or not.
As I understood, getAverage() should clearly be a const method while isUptoDate can be mutable (its not part of the logical state but just a private implementation detail). However, updateAverage() is definitely not const and I cannot call it from within a const method.
What is wrong with my approach?
It looks fine to me, you just need to make your average also mutable, because it'll be lazily computed by getAverage. updateAverage should also be const, because it will be called by getAverage. Since updateAverage is private, its own existence is an implementation detail. It's called only once, you could as well inline it into getAverage:
double getAverage() const {
if (!isUptoDate){
if(N>0){average = sum / N;}
else {average = 0;}
isUptoDate = true;
}
return average;
}
Indeed, I really suggest you inline it, because it makes no sense to have it in the header file (you have to recompile all the users if you change its signature or its const-ness). If it's not just 3 lines in the real case, you can have it as a lambda, if you use C++11:
double getAverage() const {
auto updateAverage=[&]{
if(N>0){average = sum / N;}
else {average = 0;}
isUptoDate = true;
};
if (!isUptoDate){ updateAverage(); }
return average;
}

How to guard against function arguments being passed in the wrong order?

Say I have a C++ function that looks like this:
double myfunction(double a, double b) {
// do something
}
Which I then call like this:
double a = 1.0;
double b = 2.0;
double good_r = myfunction(a, b);
double bad_r = myfunction(b, a); // compiles fine
I would like to make sure that a and b are never provided in the wrong order.
What is the best way to ensure this in C++?
Other languages allow named parameters, like this:
double good_r = myfunction(a=a, b=b);
double bad_r = myfunction(a=b, b=a); // mistake immediately obvious
double bad_r = myfunction(b=b, a=a); // compiles fine
Or perhaps the problem can be partly solved using types, i.e.
double my_type_safe_function(a_type a, b_type b) {
// do something
}
a_type a = 1.0;
b_type b = 2.0;
double good_r = myfunction(a, b);
double bad_r = myfunction(b, a); // compilation error
EDIT: A couple of people have asked what I mean by the "wrong order." What I mean is that, in real code a and b have some significance. For example, the arguments might instead be height and width. The difference between them is very important for the function to return the correct result. However, they are both floats and they both have the same dimensions (i.e. a length). Also, there is no "obvious" order for them. The person writing the function declaration may assume (width, height) and the person using the function may assume (height, width). I would like a way to ensure this doesn't happen by mistake. With two parameters it is easy to be careful with the order, but in a large project and with up to 6 arguments mistakes creep in.
Ideally I would like the checks to be done at compile time, and for there to be no performance hit (i.e. at the end of the day they are treated as plain old floats or whatever).
How about this:
struct typeAB {float a; float b; };
double myfunction(typeAB p) {
// do something
return p.a - p.b;
}
int main()
{
typeAB param;
param.a = 1.0;
param.b = 2.0;
float result = myfunction(param);
return 0;
}
Of course, you can still mess up when you assign your parameter(s) but that risk is hard to avoid :)
A variant is to have one struct per "new" type, and then make them go away in optimized builds using macros.
Something along these lines (only slightly tested, so it could be way off):
#define SAFE 0
#if SAFE
#define NEWTYPE(name, type) \
struct name { \
type x; \
explicit name(type x_) : x(x_) {}\
operator type() const { return x; }\
}
#else
#define NEWTYPE(name, type) typedef type name
#endif
NEWTYPE(Width, double);
NEWTYPE(Height, double);
double area(Width w, Height h)
{
return w * h;
}
int main()
{
cout << area(Width(10), Height(20)) << endl;
// This line says 'Could not convert from Height to Width' in g++ if SAFE is on.
cout << area(Height(10), Width(20)) << endl;
}
I think you already provided the easiest solution, using types.
One alternative could be using a builder class and method chaining.
Like:
class MyfunctionBuilder {
MyFunctionBuilder & paramA(double value);
MyFunctionBuilder & paramB(double value);
double execute();
(...)
}
Which you would use like this:
double good_r = MyFunctionBuilder().paramA(a).paramB(b).execute();
But this is a lot of extra code to write!
What is the "wrong order" actually? In this example of yours
double myfunction(double a, double b) {
// do something
}
double a = 1.0;
double b = 2.0;
double good_r = myfunction(a, b);
double bad_r = myfunction(b, a);
how do you actually want to know if this is the right order? What if the variables would be named "quapr" and "moo" instead of "a" and "b"? Then it would be impossible to guess whether the order is right or wrong just by looking at them.
With this in mind, you can do at least two things. First, is to give meaningfull names to the arguments, e.g.
float getTax( float price, float taxPercentage )
instead of
float getTax( float a, float b )
Second, do the necessary checks inside:
float divide( float dividend, float divisor )
{
if( divisor == 0 )
{
throw "omg!";
}
}
It is possible to do more complex checks, such as making a functor, and setting it's parameters explicitly, but in most of the cases that just complicates things without much benefit.

Invalid use of class in C++?

hi im trying to pass some values to a class but it wont let me it says invalid use of class 'Figure' im trying to send 3 values x,y,z and thats all but it wont let me heres what im trying to do...
here is the main.cpp and the function that calls the class Figure
for (j = 0; j < num_elems; j++) {
/* grab and element from the file */
vlist[j] = (Vertex *) malloc (sizeof (Vertex));
ply_get_element (ply, (void *) vlist[j]);
int vert=sprintf(szFile,"vertex: %g %g %g", vlist[j]->x, vlist[j]->y, vlist[j]->z);
/* print out vertex x,y,z for debugging */
TextOut(hDC,600,j*20,szFile,vert);
DrawFig->Figure(vlist[j]->x, vlist[j]->y, vlist[j]->z);
}
The error is here
DrawFig->Figure(vlist[j]->x, vlist[j]->y, vlist[j]->z);
}
Here is the WM_CREATE: where i initialize everything
case WM_CREATE:
hDC = GetDC(hWnd);
//ShowWindow(g_hwndDlg,SW_SHOW);
hRC=wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
g_hwndDlg = CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG1),hWnd,DialogProc);
DrawFig= new Figure(1.0,1.0,1.0);
initGL();
break;
here is the Figure.h
class Figure
{
public:
Figure(float x,float y,float z);
void Draw();
float paramx(){
return x1;
}
float paramy(){
return y1;
}
float paramz(){
return z1;
}
protected:
private:
float x1,y1,z1;
list <Figure> m_vertices;
};
and here is the Figure.cpp
Figure::Figure(float x,float y,float z){
this->x1=x;
this->y1=y;
this->z1=z;
m_vertices.push_back(Figure(x1, y1, z1));
}
void Figure::Draw()
{
list<Figure>::iterator p = m_vertices.begin();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0,0.0,4.0,0.0,0.0,0.0,0.0,1.0,0.0);
glColor3f(0.7f,1.0f,0.3f);
glBegin(GL_LINE_LOOP);
while(p != m_vertices.end()){
glNormal3f(p->paramx(),p->paramy(),p->paramz());
glVertex3f(p->paramx(),p->paramy(),p->paramz());
p++;
}
glEnd();
}
any ideas? this is opengl,c++ and im using codeblocks 10.05 just in case
oh yeah im initializing it at the main.h like this DrawFig* Figure;
#dark_charlie's answer is almost correct. Here is a better version that will actually work, but still probably isn't what you want:
class Figure {
// ...
public:
void set(float x, float y, float z);
// ...
};
void Figure::set(float x, float y, float z)
{
// Your original code from the constructor
this->x1 = x;
this->y1 = y;
this->z1 = z;
}
Figure::Figure(float x, float y, float z)
{
// In the constructor call the newly created set function
set(x, y, z);
m_vertices.push_back(Figure(x1, y1, z1));
}
// Replace the faulty line with this:
DrawFig->set(vlist[j]->x, vlist[j]->y, vlist[j]->z);
Now, this is almost certainly not what you want. But it's also really hard to figure out what you do want. You have a design problem. The design problem is that Figure has two responsibilities. It is both a point in space, and a set of points describing a figure. This confusion of responsibilities is leading your class to not actually be able to fill either of them particularly well.
You need two classes. You need a Point class and a Figure class. The Figure class should allow you to set the location of the figure as well as letting you add points to the figure's outline.
The huge clue that something is wrong is this list<Figure> m_vertices;. It's very rare that a class conceptually contains instances of itself. And usually when you do it you're building your own data structure like a tree or a list and then the class contains pointers to instances of itself.
Also, the fact that #dark_charlie's simple fix resulted in infinite recursion is another huge clue that something is wrong.
I'm guessing this is a homework assignment, so this is all the help I will give you aside from telling you that I think you already have a Point class that you call Vertex.
Just about the direct constructor call:
Use this instead:
// destruct and reconstruct
DrawFig -> ~Figure();
new (DrawFig) Figure(vlist[j]->x, vlist[j]->y, vlist[j]->z);
What it does:
It calls the destructor.
The destructor itself will call the destructor of all member variables. floats don't need/have a destructor but std::list has. std::lists destructor will free all containing objects.
It calls the constructor.
The constructor itself will call the constructor of all member variables. Again, floats don't have that and they are not initialized in a specific way, i.e. they are ignored again. Then the constructor of std::list is called which will initialize the list.
However, using dark_charlie's solution might be more clean.
Not only is DCs solution more clean, it also does something different. By calling the constructor again, you would also reset Figure::m_vertices and I think this is probably not what you want here.
However, maybe instead of set (like in DCs solution) you should name it add or so instead.
Also I am not sure if you really want to have Figure or Figure::m_vertices that way (each Figure containing a list to other Figures).
You cannot call a constructor directly in the way you attempt to. Create a set() function that will do the same work and use it instead of the constructor:
class Figure {
// ...
public:
void set(float x, float y, float z);
// ...
};
void Figure::set(float x, float y, float z)
{
// Your original code from the constructor
this->x1 = x;
this->y1 = y;
this->z1 = z;
// m_vertices.push_back(Figure(x1, y1, z1));
}
Figure::Figure(float x, float y, float z)
{
// In the constructor call the newly created set function
set(x, y, z);
}
// Replace the faulty line with this:
DrawFig->set(vlist[j]->x, vlist[j]->y, vlist[j]->z);
EDIT:
As noted in the comments, the code has yet another flaw - you have a list of figures that is contained within the Figure itself. I think you meant to declare m_vertices as follows:
list <Vertex> m_vertices;
Then, however, if you want a Figure to be a triangle (or any other higher-order polygon), you will need to pass coordinates of all three vertices instead of the three coordinates of one vertex:
void Figure::set(const Vertex& v1, const Vertex& v2, const Vertex& v3)
{
m_vertices.push_back(v1);
m_vertices.push_back(v2);
m_vertices.push_back(v3);
// The position of the figure will be its centroid
this->x1 = (v1.x + v2.x + v3.x) / 3;
this->y1 = (v1.y + v2.y + v3.y) / 3;
this->z1 = (v1.z + v2.z + v3.z) / 3;
}
Figure::Figure(const Vertex& v1, const Vertex& v2, const Vertex& v3)
{
set(v1, v2, v3);
}
You will also need to adjust the loop to read 3 vertices at once instead of only one but I'll let that up to you :)
A few things:
Did you instantiate the Figure class?
Is the list <Figure> m_vertices; instantiated?
The usage of using C's malloc function with the C++ runtime code is messy, best to stick with new instead to keep the C++ runtime consistent.