erase-remove idiom problems for vector in a class - c++

I am using class1 that contains a few governing variables and a vector of another class, class2. I would like to be able to flag various elements of the vector of class2 (using boolean variable 'delete_me') and then run the erase-remove idiom to eliminate those elements from the vector. I have found some examples of this on the web, but these are for simpler data structures than what I am using.
I am getting a type conversion error when I compile (using g++ v4.7.3).
Class2:
class Interval_structure {
//class uses default destructor
public:
float x1, x2, y1, y2;
float A;
float B;
float delta_x;
bool delete_me;
etc...
Class 1:
class CMR_Spline {
//class uses default destructor
public:
vector< Interval_structure > Interval;
int some_ints;
float some_floats;
bool IsMarkedToDelete( Interval_structure& o )
{
return o.delete_me;
}
void prune_Intervals() {
//intervals that have been slated for deletion are removed using the remove-erase idiom
Interval.erase( remove_if(Interval.begin(), Interval.end(), IsMarkedToDelete ), Interval.end() );
}
When I compile I get the following error, cited for the single line in the prune_Intervals routine using erase+remove_if:
error: cannot convert CMR_Spline::IsMarkedToDelete' from typebool (CMR_Spline::)(Interval_structure&) ' to type `bool (CMR_Spline::*)(Interval_structure&)'
I'm a little confused as to how I should write the IsMarkedToDelete function and prune_Intervals routine to correctly reflect the pointer that is used by remove-if to traverse the vector and evaluate IsMarkedToDelete.
How do I do this correctly using erase+remove_if, or if not that way please suggest an alternative approach. I am stumped and hindered by my limited programming experience. Thanks!

Make the function static:
static bool IsMarkedToDelete( Interval_structure& o )
{
return o.delete_me;
}

Related

C++ function with different return types

Let's say I want to write a function that takes a plane and a line in R^3 and returns their intersection. Obviously, I have to distinguish between three possible cases: i) the line intersects the plane in a single point, ii) the line is a subset of the plane, iii) the line is parallel to the plane (and not a subset of it). This results in three possible return types for the function.
I've been working a lot with OCaml recently, which would allow me to distinguish between these different types very explicitly by returning a variant type from my function. How do people deal with this kind of issue in C++?
One idea that comes to mind is to use a tuple of {bool, bool, vector} as my return type, where the first boolean says whether the line and the plane have a non-empty intersection, the second boolean says whether they intersect in a single point if the first boolean is true (and is meaningless otherwise), and the vector returns the unique intersection if both booleans are true (and is meaningless otherwise). However, this feels very inelegant and hacky, I have to inform users of the function of the meaning of the tuple entries using comments, I return variables which can be meaningless, etc.
What is the best way to deal with this problem?
Here are several generic (i.e. not limited to geometrical lines and points) ways to cope with the problem.
std::variant (or its older sibling boost::variant for those who cannot run C++17).
Plain old union (tagged):
struct LinePlaneIntersection {
enum { IsLine, IsPlane } intersection_type;
union {
Point p;
Line l;
};
};
If Point and Line have not-trivial constructors and/or destructors, you'd need to add ctors and dtors to the above scheme.
Plain old inheritance.
class LinePlaneIntersection { ... };
class NoIntersection : public LinePlaneIntersection { ... };
class OnePointIntersection : public LinePlaneIntersection { ... };
class OneLineIntersection : public LinePlaneIntersection { ... };
Return a LinePlaneIntersection* (or better and much preferable std::unique_ptr<LinePlaneIntersection>) from your function. Then there's of course the problem of what to do with the returned value. You may want to use the Visitor pattern here.
Continuation passing. Don't return anything, accept a continuation instead. In this case, three continuations:
void intersect (Line line, Plane plane,
std::function<void(Line)> onLine,
std::function<void(Point)> onPoint,
std::function<void()> onNothing);
I would do something like:
struct Point3D
{
double x;
double y;
double z;
};
struct Line
{
Point3D p1;
Point3D p2;
};
struct Plan {
Point3D p;
Point3D orthogonalDir;
};
std::optional<std::variant<Point3D, Line>>
ComputeIntersection(const Line& line, const Plan& plan);
Although there are nice new shiny ways of dealing with this (std::tuple, std::variant, &c.), the tried-and-tested way is to design a class (or even a set of related classes) that can represent the various states and return an instance of that.
It's this approach that always seems to scale up best as your project evolves. So much so, that the committee behind Java has never emitted a tuple or a variant type into their language and libraries.
Why not return a struct with an enum type? Someone using the function could then first check the type of intersection before attempting to use the data.
enum IntersectType {
INTERSECTION_NONE,
INTERSECTION_POINT,
INTERSECTION_LINE,
};
struct Point3D {
double x;
double y;
double z;
}
struct LinePlaneIntersect {
IntersectType type;
std::vector<Point3D> intersect; //since you mentioned vector
};
//Check within another function
struct LinePlaneIntersect intersection = fun(line, plane);
if (intersection.type == INTERSECTION_POINT) {
// do something
}

Using Boost bisection when the function relies on a class attribute and has additional arguments

I am trying to use the Boost bisection method described here.
I have seen a couple of examples of how to get this to work, e.g. How to use boost bisection?, but I don't understand how to apply these to my particular set-up.
Here is a sketch of some code that illustrates what I am trying to do.
class Model {
double b;
double root;
public:
double func(double x, double c);
void solve(void);
};
double Model::func(double x, double c) {
return (x*x*x + (b*x) + c);
}
void Model::solve(void) {
double c;
b = 2.;
c = 1.;
// root = bisect(func(), from, to, ...);
// where the first argument to func() is what we want to find the root over
// and the second argument to func() is c
}
int main(void) {
Model model;
model.solve();
}
The member function solve() needs to find the root of the member function func(). func() has two important features:
It relies on the class attribute b
It has a second argument c that is determined in solve(). I want to hold this second argument fixed when finding the root
How would I implement the Boost bisection method in this context? This answer seems to suggest that boost::bind might solve part of the problem but I don't understand enough of it to know how to apply it to my problem.

g++ error: field has incomplete type

I'm trying to work with inner classes. I need to call get function from the nested class. What am I doing wrong? Thank you for your time!
class Discriminant
{
private:
float d;
public:
void calcDiscr(int temp_a,int temp_b,int temp_c)
{
d = (temp_b^2)-4*temp_a*temp_c;
}
float get_d()
{
return d;
}
class Result
{
private:
float x1,x2;
public:
Discriminant tempObject1;//here comes the error
void calcResult(int temp_a,int temp_b,int temp_c)
{
cout<<"object's d = "<<tempObject1.get_d();
x1 = (-temp_b+sqrt(tempObject1.get_d()))/2*temp_a;
x2 = (-temp_b-sqrt(tempObject1.get_d()))/2*temp_a;
}
void displayResult()
{
cout<<endl<<"x1 = "<<x1;
cout<<endl<<"x2 = "<<x2;
}
};
};
When the compiler reads the
Discriminant tempObject1;//here comes the error
line, the definition of Discriminant has not been fully parsed (hence the incomplete type error); which only ends with the final ;, closing the class Discriminant statement.
Theoretical solutions that do not require Discriminant to be a fully-defined type are to make tempObject1 either:
Discriminant*
Discriminant&
Of which only solution #1 is feasible.
That is your code, that doesn't compile:
class Discriminant
{
// etc.
class Result
{
// etc.
Discriminant tempObject1; //here comes the error
};
};
The problem is, like reported by haavee, that Discriminant is not fulled parsed (and thus incomplete) when you try to make it a member of Result.
One solution is to make tempObject1 a pointer, instead of a value.
Another solution is to define Result after Discriminant (I assume you want to keep the IMHO awful inner class style). The code becomes:
class Discriminant
{
// etc.
class Result;
};
class Discriminant::Result
{
// etc.
Discriminant tempObject1; // No error!
};
This should solve your compilation problem.
P.S.: I missed the first part of your question:
I'm trying to work with inner classes. I need to call get function from the nested class.
I hope your using nested classes is not an attempt to use Java's bizarre version's.
If you expect your inner class to have a pointer/reference to the outer class like in Java, you will be disappointed. This is a Java peculiarity. C++ and C# don't implement this bizarre feature. You'll have to pass the pointer manually.

is that possible to define different type of variable based on the input variable in c++?

I am developing an algorithm in which I need to define one vector as real or complex depending on the input variable. The pseudo is like
void foo(bool is_real)
{
if (is_real)
{
vector< double > v;
}
else vector< complex > v;
}
Now I am writing two different version of algorithms, if is_real is true, I will use the algorithm for real case, otherwise, use the complex case. Actually, both algorithms are exact same except for the data type. So I google it and
#if is_real
vector< double > v;
#else
vector< complex > v;
#endif
But this code doesn't compile. I am using linux gnu c++ 4.7.2. I wonder if the macro only works for microsoft c++? I feel not comfortable since in my implementation the only difference will be data type, is there any way to select what type should be used in runtime? Thanks.
If the code is exactly the same, make it a template:
namespace detail {
template <typename T>
void foo() {
vector<T> v;
// blah
}
}
void foo(bool is_real)
{
if (is_real)
{
detail::foo<double>();
}
else detail::foo<complex>();
}
C++ templates need to know their types at compile time. In you first example the types are defined at run time which is not allowed in C++ which is a rather static language. The second example uses compile time conditionals and so is fine.
The macro is used by the Preprocessor it's a compile time instruction, You can't use it during run time. It assumes that you will define something and let the compiler know that you're working with real or complex numbers during compilation.
You can use templates (like suggested), but if you wish to initialize it in one place and then continue to work with the vectors you have several options -
Use inheritance and work with the vector of the base class
Have two vectors and only work with one (depending on the input)
Store your real numbers inside as complex numbers. It's a bit wasteful though.
What your are trying to achieve with is_real can be done at compile time using -Dis_real option
At runtime you can have something like this :
template<typename T>
class MyAlgorithm
{
public:
MyAlgorithm(/*...*/ )
{
/*Your initialization routine */
}
/* copy constructor
copy assignment operator */
~MyAlgorithm(/*...*/){ /*...Other deallocation stuffs...*/ }
private:
std::vector<T> vec;
};
int main ()
{
MyAlgorithm<double> m;
MyAlgorithm<std::complex<double> > n;
return 0;
}

Referencing variables in a structure / C++

Below, I provided a minimal example of code I created. I managed to get this code working, but I'm not sure if the practice being employed is sound. In essence, what I am trying to do is have the 'Parameter' class reference select elements in the 'States' class, so variables in States can be changed via Parameters.
Questions I have: is the approach taken OK? If not, is there a better way to achieve what I am aiming for?
Example code:
struct VAR_TYPE{
public:
bool is_fixed; // If is_fixed = true, then variable is a parameter
double value; // Numerical value
std::string name; // Description of variable (to identify it by name)
};
struct NODE{
public:
VAR_TYPE X, Y, Z;
/* VAR_TYPE is a structure of primitive types */
};
class States{
private:
std::vector <NODE_ptr> node; // shared ptr to struct NODE
std::vector <PROP_DICTIONARY_ptr> property; // CAN NOT be part of Parameter
std::vector <ELEMENT_ptr> element; // CAN NOT be part of Parameter
public:
/* ect */
void set_X_reference ( Parameter &T , int i ) { T.push_var( &node[i]->X ); }
void set_Y_reference ( Parameter &T , int i ) { T.push_var( &node[i]->Y ); }
void set_Z_reference ( Parameter &T , int i ) { T.push_var( &node[i]->Z ); }
bool get_node_bool_X( int i ) { return node[i]->X.is_fixed; }
// repeat for Y and Z
};
class Parameter{
private:
std::vector <VAR_TYPE*> var;
public:
/* ect */
};
int main(){
States S;
Parameter P;
/* Here I initialize and set S, and do other stuff */
// Now I assign components in States to Parameters
for(int n=0 ; n<S.size_of_nodes() ; n++ ){
if ( S.get_node_bool_X(n)==true ){
S.set_X_reference ( P , n );
};
// repeat if statement for Y and Z
};
/* Now P points selected to data in S, and I can
* modify the contents of S through P
*/
return 0;
};
Update
The reason this issue cropped up is I am working with Fortran legacy code. To sum up this Fotran code - it's a numerical simulation of a flight vehicle. This code has a fairly rigid procedural framework one must work within, which comes with a pre-defined list of allowable Fortran types. The Fortran glue code can create an instance of a C++ object (in actuality, a reference from the perspective of Fortran), but is not aware what is contained in it (other means are used to extract C++ data into Fortran).
The problem that I encountered is when a C++ module is dynamically linked to the Fortran glue code, C++ objects have to be initialized each instance the C++ code is called. This happens by virtue of how the Fortran template is defined.
To avoid this cycle of re-initializing objects, I plan to use 'State' as a container class. The Fortran code allows a 'State' object, which has an arbitrary definition; but I plan to use it to harness all relevant information about the model. The idea is to use the Parameters class (which is exposed and updated by the Fortran code) to update variables in States.
What you are doing is legal C++ (although some parts of the code are missing, so I have to guess what they do) -- you can take pointers and references to member variables like this. But the question whether this is moral (or "sound") depends heavily on the situation.
It seems to me that you are trying to hide the semantics of which data member (x, etc) a particular object belongs to with your Parameter type. So, when actually accessing the contents of your VAR_TYPE* collection, you will not have that information.
That could be desired or it could be code smell. I'm leaning towards the latter. If x, y and z can serve similar roles, it might be better to replace them by one std::array<VAR_TYPE,3> and access them by index rather than going to the trouble of creating this wrapper type that serves the only purpose to add exactly this indirect access functionality.