how to use find algorithm in C++ with Objects

how do i use the find algorithm to check if a certain object exists in a vector.
I have a base class called Shape and derived classes Circle and Line.
Circle has 3 attributes , x location , y location and radius.

I would like to check if the Circle c1(1,1,1) exists in the vector<std::shared_ptr<Shape>> v.

Hi

Sounds like you need to specify a predicate function

http://en.cppreference.com/w/cpp/algorithm/find look at the examples.

http://en.cppreference.com/w/cpp/concept/Predicate

Btw, Line should not be derived from Shape because it is not a Shape. Functions like Area and perimeter should be able to be applied to all classes derived from Shape.

https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
Further about the inheritance:

One could have this inheritance tree:

1
2
3
4
5
6
7
8
class DrawingEntity; // has a virtual draw function which is inherited by all derived classes
class Shape : public DrawingEntity;  // virtual Area and Perimeter functions
class Triangle : public Shape;
class Circle  : public Shape;
class RegularPolygon : public Shape;

class Line : public DrawingEntity;
class Annotation : public DrawingEntity; // graphical text 
so Line should not derive from Shape ?
Consider unsing find_if(). See:

http://www.cplusplus.com/reference/algorithm/find_if/?kw=find_if

Using lambda:
1
2
3
4
5
6
std::vector<std::shared_ptr<Shape>>::iterator it = std::find_if(v.begin(), v.end(), [](std::shared_ptr<Shape> shape)
{
std::shared_ptr<Circle> c = std::dynamic_pointer_cast<Circle>(shape);
...
return is_ok;
});


so Line should not derive from Shape ?
Generally: If a class needs things provided by another class it may inherit from that class. Since a line has a with it is rather a special case of a rectangle. So I would say yes, a line is a kind of shape.
masterinex wrote:
so Line should not derive from Shape ?


TheIdeasMan wrote:
Btw, Line should not be derived from Shape because it is not a Shape. Functions like Area and perimeter should be able to be applied to all classes derived from Shape.

https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)


Here's the thinking behind the inheritance tree above:

Public inheritance implies a "IS A" relationship. In the SOLID wiki page, the L is for Liscov substitution. So functions like Area and perimeter should be able to be applied to base and derived class Shapes. Line doesn't fit into inheritance from Shape, neither does Annotation. But one thing they all have in common is a draw function, so I made the DrawingEntity base class, and all the derived classes inherit and override it's virtual draw function.

Now one can have a container of pointer or reference (via std::reference_wrapper) to DrawingEntity (the base class). We populate this with pointers / references to the derived classes. Next use a range base for loop to call the draw function via each pointer/reference. The compiler calls the correct function because a pointer/reference to a derived class is a valid reference to a base class . This is why there is no need for a dynamic_cast.
Last edited on
I'm new to lamda expressions: Should not the lambda expression be like this :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
std::vector<std::shared_ptr<Shape>>::iterator it = std::find_if(v.begin(), v.end(), [](std::shared_ptr<Shape> shape) -> bool
{
  std::shared_ptr<Circle> c= std::dynamic_pointer_cast<Circle>(shape);

   bool is_ok = false; 

  if(c)
  {
     is_ok = true;
     return is_ok; 
   }
  else
   {
     return is_ok;
   }

});


hope it works.
Last edited on
-> bool determines the return value. It can usually be automatically determined by the compiler when using the return statement (or not -> void).

So simplified:
1
2
3
4
5
6
7
8
9
10
11
12
13
std::vector<std::shared_ptr<Shape>>::iterator it = std::find_if(v.begin(), v.end(), [](std::shared_ptr<Shape> shape)
{
  std::shared_ptr<Circle> c= std::dynamic_pointer_cast<Circle>(shape);

   bool is_ok = false; 

  if(c)
  {
     is_ok = ((*c) == Circle{1,1,1}); // Note: You need to overload operator==(...) in order to make this work.
   }
     return is_ok;

});
Topic archived. No new replies allowed.