Related
As an old c99 person, I was often stubled upon the curly brakets initialization. In the `initializer_list`, I have to use {r, i} for a complex number. On the other hand, I have to use (r, i) for `complex` in the istream field. Here, I cut a part of my class that is able to run and give examples under codeblock 20.03 with MinGW 8.1.0.
#ifndef __tMatrix_class__
#define __tMatrix_class__
#include <iostream>
#include <initializer_list>
#include <iomanip>
#include <complex>
#include <sstream>
template <typename T> class tMatrix
{
public:
T *ptr;
int col, row, size;
inline T* begin() const {return ptr;}
inline T* end() const {return this->ptr + this->size;}
inline T operator()(const int i, const int j) const { return ptr[i*col+j]; } // r-value
inline T&operator()(const int i, const int j) { return ptr[i*col+j]; } //l-value
inline tMatrix(): col{0}, row{0}, size{0}, ptr{0} {;}
tMatrix(const int i, const int j): col(j), row(i), size(i*j) {
ptr = new T [this->size] ; }
tMatrix(const std::initializer_list< std::initializer_list<T> > s):tMatrix<T>(s.size(), s.begin()->size())
{
int j = 0;
for (const auto& i : s) { std::copy (i.begin(), i.end(), ptr + j*col); ++j ; }
}
tMatrix(const tMatrix<T>&a) : tMatrix<T>(a.row, a.col)
{
std::copy(a.begin(), a.end(), this->ptr);
}
tMatrix<T>& operator=(tMatrix<T>&&a)
{
this->col = a.col;
this->row = a.row;
delete [] this->ptr;
this->ptr = a.ptr;
a.ptr = nullptr;
return *this;
}
tMatrix<T>& operator=(const tMatrix<T>&a)
{
if (col==a.cpl && row==a.row) std::copy(a.begin(), a.end(), this->ptr);
else { tMatrix<T>&&v(a); *this = std::move(v);}
return *this;
}
tMatrix<T>& operator=(const std::initializer_list<std::initializer_list<T> > a)
{
tMatrix<T> &&v = a;
*this = std::move(v);
return *this;
}
~tMatrix() {delete [] this->ptr;}
void operator<<(const char*s)
{
std::stringstream ss;
ss.str(s);
for (int i=0; i<this->size; i++){
if (ss.good()) ss >> this->ptr[i];
else return;
}
}
}; //end of class tMatrix
template <typename X> std::ostream& operator<<(std::ostream&p, const tMatrix<X>&a)
{
p << std::fixed;
for (int i=0; i<a.row; i++) {
for (int j=0; j <a.col; j++) p << std::setw(12) << a(i, j);
p << std::endl;
}
return p;
}
using CMPLX = std::complex<double>;
using iMatrix = tMatrix<int>;
using rMatrix = tMatrix<double>;
using cMatrix = tMatrix< CMPLX >;
#endif
int main()
{
cMatrix cx(2,2);
cx = { { {1,2},{3,4} }, { {5,6}, {7,8} } };
std::cout << cx << std::endl;
cx << "(1,2) (3,4)";
std::cout << cx << std::endl;
return 0;
}
The above code renders correct format of complex number, and prints
$ ./ttt_mtx_init_fin_tmp.exe
(1.000000,2.000000)(3.000000,4.000000)
(5.000000,6.000000)(7.000000,8.000000)
(1.000000,2.000000)(3.000000,4.000000)
(5.000000,6.000000)(7.000000,8.000000)
But if I use the `()` in the initializer_list and `{}` in the istream filed, the results are all wrong. If I chagned the relavant part of main() to :
cx = { { (1,2),(3,4) }, { (5,6), (7,8) } };
std::cout << cx << std::endl;
cx << "{1,2} {3,4}";
std::cout << cx << std::endl;
Which renders all wrong values (compared with above):
$ ./ttt_mtx_init_fin_tmp.exe
(2.000000,0.000000)(4.000000,0.000000)
(6.000000,0.000000)(8.000000,0.000000)
(2.000000,0.000000)(4.000000,0.000000)
(6.000000,0.000000)(8.000000,0.000000)
I found it is rather confusion. So, my questions: is there a way to make these two expressions a same form? Many thanks for any helps.
I do not know any way to make std::istream::operator>> use { and } for std::complex, but if you are fine with using a helper, then you can replace the () in the input with {} and forward the input to the original operator>>:
#include <iostream>
#include <complex>
#include <sstream>
#include <algorithm>
template <typename T>
struct complex_reader {
std::complex<T>& target;
};
template <typename T>
complex_reader<typename T::value_type> get_complex_reader(T& t){ return {t};}
template <typename T>
std::istream& operator>>(std::istream& in,complex_reader<T> cr){
std::string input;
std::getline(in,input,'}'); // read till `}`
std::replace(input.begin(),input.end(),'{','(');
input += ')';
std::stringstream ss{input};
ss >> cr.target; // call the original >>
return in;
}
int main()
{
std::stringstream ss{"{2,2}"};
std::complex<double> x;
ss >> get_complex_reader(x);
std::cout << x;
}
Output:
(2,2)
However, you would have to write a similar helper to get consistent output (you may not provide an operator<< for std::complex<T> directly). Also note that the above implementation is a little simplistic. It reads from the stream until it encounters a }. For invalid input this may result in undesired effects and more sophisticated input validation is required.
Note that the operator>> takes the complex_helper by value to allow passing temporaries. Thats fine, because the member is a (non-const) reference.
This is not an answer, but a reasoning of my choice. After a series of cross conversions with `largest_prime_is_463035818`, I figured out what is my best choice for now (many thanks to his time and patience). A bottom line is becoming clear to me that I will not alter the input format of istream that is too much changed for pratical purpose, since file input is the major method to fetch data for a large matrix.
Under this constrain, I try to make the appearance of initializer_list as friendly as possible. I did some experiments, and found that the complex_literals expression is acceptable by initializer_list. And it looks ok to me.
using namespace std::complex_literals;
int main()
{
cMatrix cx(3,2);
cx = { { 1+2.2j , 4j}, { 5.3+6.5j , 8.3j}, {8.3, 5.6+4j} };
std::cout << cx << std::endl;
cx << " (1,2) (3,4) (5,6) (7,8) (2.3, 3.4) (2,7.8) ";
std::cout << cx << std::endl;
return 0;
}
And it works.
$ ./a.exe
(1.000000,2.200000) (0.000000,4.000000)
(5.300000,6.500000) (0.000000,8.300000)
(8.300000,0.000000) (5.600000,4.000000)
(1.000000,2.000000) (3.000000,4.000000)
(5.000000,6.000000) (7.000000,8.000000)
(2.300000,3.400000) (2.000000,7.800000)
Thank you for your patience, and please let me know if there are better ways.
I have made a class called Point which simply contains a tuple of x y coordinates. I also made a vector of the Type Point and added the point (3,4). Now i want to search this vector for the point with binary search, and if it return true then i want to print "yes", to confirm that the point exists in the vector. Unfortunately, the find function doesnt work on a vector of type Point, how can fix this?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Point {
private:
double xval, yval;
public:
// Constructor uses default arguments to allow calling with zero, one,
// or two values.
Point(double x = 0.0, double y = 0.0) {
xval = x;
yval = y;
}
// Extractors.
double x() { return xval; }
double y() { return yval; }
};
int main()
{
vector<Point> points;
points.push_back(Point(3,4));
if (binary_search(points.begin(),points.end(),Point(3,4)))
{cout<<"The point exists"<<endl;}
return 0;
}
Since you have a custom type array, you must define a comparing function in order to tell which criteria should be followed to consider an element greater than the other. There is an example in C++ Reference:
// binary_search example
#include <iostream> // std::cout
#include <algorithm> // std::binary_search, std::sort
#include <vector> // std::vector
bool myfunction (int i,int j) { return (i<j); }
int main () {
int myints[] = {1,2,3,4,5,4,3,2,1};
std::vector<int> v(myints,myints+9); // 1 2 3 4 5 4 3 2 1
// using default comparison:
std::sort (v.begin(), v.end());
std::cout << "looking for a 3... ";
if (std::binary_search (v.begin(), v.end(), 3))
std::cout << "found!\n"; else std::cout << "not found.\n";
// using myfunction as comp:
std::sort (v.begin(), v.end(), myfunction);
std::cout << "looking for a 6... ";
if (std::binary_search (v.begin(), v.end(), 6, myfunction))
std::cout << "found!\n"; else std::cout << "not found.\n";
return 0;
}
The vector should be sorted, and you should provide same comparer to std::binary_search.
either provide
bool operator < (const Point& lhs, const Point& rhs)
{
return std::tuple(lhs.x(), lhs.y()) < std::tuple(rhs.x(), rhs.y());
}
or custom comparer
auto comp = [](const Point& lhs, const Point& rhs){
return std::tuple(lhs.x(), lhs.y()) < std::tuple(rhs.x(), rhs.y());
};
if (binary_search(points.begin(), points.end(), Point(3,4), comp)) {/**/}
I'm looking to get intersection of two custom vectors - v and w - and then deleting common elements from original vector - v. But somehow size of y in my case is 0 always
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class A{
public:
int x;
A(int i) { x = i; }
~A() {}
void getx() { cout << x << " "; }
friend ostream &operator<<(ostream &o, const A&a) {
cout << a.x;
return o;
}
};
struct mycomparer {
bool operator()(const A* a, const A* b) {
return a->x < b->x;
}
};
int main()
{
vector<A*> v;
v.push_back(new A(1));
v.push_back(new A(2));
v.push_back(new A(4));
v.push_back(new A(3));
v.push_back(new A(5));
vector<A*> w;
w.push_back(new A(3));
w.push_back(new A(2));
vector<A*> y;
vector<A*>::iterator it, st;
it = set_intersection(v.begin(), v.end(), w.begin(), w.end(), y.begin(), mycomparer());
cout << " y size " << y.size() << endl;
if (y.size()) {
for (st = y.begin(); st != y.end(); st++)
v.erase(st);
}
for (st = v.begin(); st != v.end(); st++) {
printf("%d ", (*st)->x);
}
cout << endl;
return 0;
}
This is just a sample which I wrote and my intend is not to check for any other C++ rules.
You haven't obeyed the requirements of std::set_intersection.
Constructs a sorted range beginning at d_first consisting of elements that are found in both sorted ranges [first1, last1) and [first2, last2). If some element is found m times in [first1, last1) and n times in [first2, last2), the first std::min(m, n) elements will be copied from the first range to the destination range. The order of equivalent elements is preserved. The resulting range cannot overlap with either of the input ranges.
Neither v nor w are sorted w.r.t mycomparer. That's the first undefined behaviour.
Just passing y.begin() does not mean elements are added to y, for that you need std::back_inserter(y). That's the second undefined behaviour.
You haven't obeyed the requirements of std::vector::erase. It's argument is an iterator into that vector. You are using an iterator from y, not v. That's the third undefined behaviour.
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
class A{
public:
int x;
A(int i) { x = i; }
~A() {}
void getx() { cout << x << " "; }
friend ostream &operator<<(ostream &o, const A&a) {
cout << a.x;
return o;
}
};
struct mycomparer {
bool operator()(const A* a, const A* b) {
return a->x < b->x;
}
};
int main()
{
std::vector<A*> v;
v.push_back(new A(1));
v.push_back(new A(2));
v.push_back(new A(4));
v.push_back(new A(3));
v.push_back(new A(5));
std::sort(v.begin(), v.end(), mycomparer());
std::vector<A*> w;
w.push_back(new A(3));
w.push_back(new A(2));
std::sort(w.begin(), w.end(), mycomparer());
std::vector<A*> y;
set_intersection(v.begin(), v.end(), w.begin(), w.end(), std::back_inserter(y), mycomparer());
std::cout << " y size " << y.size() << std::endl;
for (st = y.begin(); st != y.end(); st++)
v.erase(std::find(v.begin(), v.end(), *st));
for (st = v.begin(); st != v.end(); st++) {
std::cout << (*st)->x) << std::endl;
}
return 0;
}
As an aside, you could instead use std::set_difference to find the elements in v not in w directly.
There are many issues with your code... I just put them in modified code
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
// don't using namespace std;
class A {
private:
int x; // don't expose internals
public:
constexpr A(int i) noexcept : x(i) {}
constexpr int GetX() const noexcept { return x; } // don't make a getter to print
friend std::ostream& operator<< (std::ostream& o, const A& a) {
o << a.x; // don't push to cout in an ostream operator <<
return o;
}
};
// use lambda instead of functors
static constexpr auto mycomparer =
[](std::shared_ptr<A> const& a, std::shared_ptr<A> const& b) noexcept {
return a->GetX() < b->GetX();
};
int main()
{
// you were not deleting the new elements: memory leak
std::vector<std::shared_ptr<A>> v; // e.g. use smart pointers
v.push_back(std::make_shared<A>(1));
v.push_back(std::make_shared<A>(2));
v.push_back(std::make_shared<A>(4));
v.push_back(std::make_shared<A>(3));
v.push_back(std::make_shared<A>(5));
std::vector<std::shared_ptr<A>> w;
w.push_back(std::make_shared<A>(3));
w.push_back(std::make_shared<A>(2));
std::vector<std::shared_ptr<A>> y;
//you have to sort before calling set_intersection
std::sort(std::begin(v), std::end(v), mycomparer);
std::sort(std::begin(w), std::end(w), mycomparer);
std::set_intersection(
std::cbegin(v), std::cend(v), // use const iterators
std::cbegin(w), std::cend(w),
std::back_inserter(y), mycomparer); // you cannot iterate over an empty array. Use the backinserter
std::cout << " y size " << y.size() << '\n';
// you cannot use an iterator to a vector y to delete from vector v!
//if (y.size() > 0) { // not required
for (auto const& el : y)
v.erase(std::find(std::cbegin(v), std::cend(v), el));
//}
for (auto const& el : v) {
std::cout << el->GetX() << " ";
}
std::cout << '\n'; // prefer \n over endl for speed
//return 0; // not required
}
1) In vector w you should push new A(2) first, then new A(3). For your actual code, your vectors must be sorted according to the comparator beforehand, as previously mentioned in commentaries, or you absolutely cannot use set_intersection.
2) vector y has size 0, because set_intersection does not insert new elements at iterator, but instead assigns with operator =. Instead of y.begin() you should use std::back_inserter(y), which would actually insert elements on assignment.
How can I print out the highest element of Valarray of complex numbers in C++ ?
I have tried with this code but it is returning error messages
#include <iostream> // std::cout
#include <valarray>
#include <complex>// std::valarray
typedef std::complex<double> Complex;
typedef std::valarray <Complex > CArray;
int main ()
{
CArray y[5]={{1, 2},{3, 4},{2,0},{7,0},{9,0}};
std::cout << "The max is " << y.max() << '\n';
return 0;
}
Output:
main.cpp: In function 'int main()':
main.cpp:15:35: error: request for member 'max' in 'y', which is of non-class type 'CArray [5] {aka std::valarray<std::complex<double> > [5]}'
std::cout << "The max is " << y.max() << '\n';
^
What I am doing wrong ?
Second version of code
I have modified a bit the code, Now I would like to get all index corresponding to the highest element of my Valarray in my case all index corresponding to element {9,0}
Note :by "Highest element" I mean element having the highest real part
new code:
#include <iostream>
#include <valarray>
#include <complex>
#include <algorithm>
#include <numeric>
typedef std::complex<double> Complex;
typedef std::valarray <Complex > CArray;
int main ()
{
CArray y={{1, 2},{3, 4},{2,0},{9,0},{7,0},{9,0}};
auto max_val = std::accumulate (std::begin(y), std::end(y), *std::begin(y),
[](const Complex& a ,const Complex& b)
{
auto abs_a = abs(a);
auto abs_b = abs(b);
//if(abs_a == abs_b)
// return std::max(arg(a), arg(b));
return std::max(abs_a, abs_b);
}
);
for (std::size_t i =std::begin(y) ; i != std::end(y) ; i++) {
std::cout << "The max is found on index ["<< i <<"]" << max_val<< '\n';
}
return 0;
}
I am getting following errors :
Output:
main.cpp: In function 'int main()':
main.cpp:22:35: error: invalid conversion from 'std::complex<double>*' to 'std::size_t {aka long unsigned int}' [-fpermissive]
for (std::size_t i =std::begin(y) ; i != std::end(y) ; i++) {
^
main.cpp:22:54: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
for (std::size_t i =std::begin(y) ; i != std::end(y) ; i++) {
^
y is an array of valarrays, so you need to call max on each element in that array, not on the array itself (which of course has no member functions).
std::complex is not a comparable type, so what does it mean to have a "highest" element?
Update: Regarding your edit, I think I understand what you're after...
For the highest index of the max (by real()) element:
std::size_t max_index(CArray const& y) {
struct acc_t {
double max_value;
std::size_t max_idx, current_idx;
constexpr acc_t next() const { return {max_value, max_idx, current_idx + 1}; }
constexpr acc_t next_with(Complex const c) const {
return {c.real(), current_idx, current_idx + 1};
}
};
return std::accumulate(
std::begin(y), std::end(y), acc_t{},
[](acc_t const acc, Complex const c) {
return c.real() < acc.max_value
? acc.next()
: acc.next_with(c);
}
).max_idx;
}
Online Demo
Or for all indices of the max element:
std::vector<std::size_t> max_indices(CArray const& y) {
struct acc_t {
std::vector<std::size_t> max_idcs;
double max_value;
std::size_t current_idx;
constexpr acc_t&& next() {
++current_idx;
return std::move(*this);
}
acc_t&& next_with_current() {
max_idcs.push_back(current_idx++);
return std::move(*this);
}
acc_t&& next_with(Complex const c) {
max_value = c.real();
max_idcs.clear();
return next_with_current();
}
};
return std::accumulate(
std::begin(y), std::end(y), acc_t{},
[](acc_t& acc, Complex const c) {
return c.real() < acc.max_value ? acc.next()
: c.real() > acc.max_value ? acc.next_with(c)
: acc.next_with_current();
}
).max_idcs;
}
Online Demo
N.b. your code has abs involved but I'm not sure why since you said you just wanted comparison based on std::complex<>::real(), so I've omitted that...
The bigger problem of your original code was (as pointed by Ildjarn) that Complex lack of operator<.
I suppose that your Complex should be a little more complex (if you allow me the play on words).
I propose the following solution were Complex derive from std::complex<double> and declare a friend operator< (). One of many operator< () possible.
#include <iostream>
#include <valarray>
#include <complex>
struct Complex: public std::complex<double>
{
template <typename ... Args>
Complex (const Args & ... args) : std::complex<double>{args...}
{ }
friend bool operator< (const Complex & c1, const Complex & c2)
{
return (c1.real() < c2.real())
|| ((c1.real() == c2.real()) && (c1.imag() < c2.imag()));
}
};
typedef std::valarray <Complex > CArray;
int main ()
{
CArray y { {1.0,2.0}, {3.0,4.0}, {2.0,0.0}, {7.0,0.0}, {9.0,0.0} };
std::cout << "The max is " << y.max() << '\n';
return 0;
}
If you accept that Complex can be a templated class (using Class<double> instead of Complex, you can write a more general solution in this way (that can be used also with complex based on float and long double)
#include <iostream>
#include <valarray>
#include <complex>
template <typename T>
struct Complex: public std::complex<T>
{
template <typename ... Args>
Complex (const Args & ... args) : std::complex<T>{args...}
{ }
friend bool operator< (const Complex & c1, const Complex & c2)
{
return (c1.real() < c2.real())
|| ((c1.real() == c2.real()) && (c1.imag() < c2.imag()));
}
};
typedef std::valarray <Complex<double>> CArray;
int main ()
{
CArray y { {1.0,2.0}, {3.0,4.0}, {2.0,0.0}, {7.0,0.0}, {9.0,0.0} };
std::cout << "The max is " << y.max() << '\n';
return 0;
}
p.s.: should work with C++11 too.
p.s.2: sorry for my bad English.
--- Edited to get the index of the max element ---
#include <iostream>
#include <valarray>
#include <complex>
template <typename T>
struct Complex: public std::complex<T>
{
template <typename ... Args>
Complex (const Args & ... args) : std::complex<T>{args...}
{ }
friend bool operator< (const Complex & c1, const Complex & c2)
{
return (c1.real() < c2.real())
|| ((c1.real() == c2.real()) && (c1.imag() < c2.imag()));
}
};
typedef std::valarray <Complex<double>> CArray;
int main ()
{
CArray y { {1.0,2.0}, {3.0,4.0}, {2.0,0.0}, {7.0,0.0}, {9.0,0.0} };
auto m = 0U;
for ( auto i = 1U ; i < y.size() ; ++i)
if ( y[m] < y[i] )
m = i;
std::cout << "The max is found on index ["<< m <<"] and is " << y[m]
<< std::endl;
return 0;
}
using std::accumulate can get max of complex numbers simillar to Matlab max function:
#include <iostream>
#include <valarray>
#include <complex>
#include <algorithm>
#include <numeric>
typedef std::complex<double> Complex;
typedef std::valarray <Complex > CArray;
int main ()
{
CArray y={{1, 2},{3, 4},{2,0},{7,0},{9,0}};
auto max_val = std::accumulate (std::begin(y), std::end(y), *std::begin(y),
[](const Complex& a ,const Complex& b)
{
auto abs_a = abs(a);
auto abs_b = abs(b);
if(abs_a == abs_b)
return std::max(arg(a), arg(b));
return std::max(abs_a, abs_b);
}
);
std::cout << "The max is " << max_val<< '\n';
return 0;
}
Edit: question edited and OP wants to get index of maximum of real part of complex numbers so your answer:
#include <iostream>
#include <valarray>
#include <complex>
#include <algorithm>
#include <numeric>
typedef std::complex<double> Complex;
typedef std::valarray <Complex > CArray;
int main ()
{
CArray y={{1, 2},{3, 4},{2,0},{7,0},{9,0}};
std::vector<int> index(y.size());
std::iota( index.begin(), index.end(), 0 );
auto max_index = std::accumulate (std::begin(index), std::end(index), *std::begin(index),
[&](int a ,int b)
{
return y[a].real() > y[b].real() ? a: b;
}
);
std::cout << "index of max is " << max_index<< '\n';
return 0;
}
Edit 2: as #ildjarn mentioned modified question wants to get all indices corresponding to the highest element so modified answer:
#include <iostream>
#include <valarray>
#include <complex>
#include <algorithm>
#include <numeric>
typedef std::complex<double> Complex;
typedef std::valarray <Complex > CArray;
int main ()
{
CArray y={{1, 2},{3, 4},{2,0},{7,0},{9,0}};
std::vector<int> index(y.size());
std::iota( index.begin(), index.end(), 0 );
auto max_index = std::accumulate (std::begin(index), std::end(index), *std::begin(index),
[&](int a ,int b)
{
return y[a].real() > y[b].real() ? a: b;
}
);
std::vector<int> indices;
std::copy_if(std::begin(index), std::end(index), std::back_inserter(indices),
[&](int a)
{
return y[a] == y[max_index];
}
);
for (auto i: indices)
std::cout << "index of max is " << i << '\n';
return 0;
}
Edit 3: using std::max_element the simplest solution we have:
#include <iostream>
#include <valarray>
#include <complex>
#include <algorithm>
#include <numeric>
#include <vector>
typedef std::complex<double> Complex;
typedef std::valarray <Complex > CArray;
int main ()
{
CArray y={{1, 2},{3, 4},{2,0},{9,0},{7,0},{9,0}};
auto max_index = std::max_element (std::begin(y), std::end(y),
[](const Complex& a ,const Complex& b)
{
return a.real() < b.real() ;
}
);
std::cout << "index of first max element is " << max_index-std::begin(y) << '\n';
std::cout << "indices of all matches of max element is: " << "[";
for (auto it= std::begin(y), end = std::end(y); it != end; ++it){
if(it->real() == max_index->real()) {
std::cout << it - std::begin(y) << ' ' ;
}
}
std::cout << "]";
return 0;
}
I would like to do something like this:
std::ofstream ch("ch_out.txt");
std::ostream_iterator< cgal_class > out( "p ", ch, "\n" );
Is this even possible? I worry because my research says no, hope it was broken. :)
The goal is to take the convex hull points produced by CGAL and write them in a file like this:
p 2 0
p 0 0
p 5 4
with this code:
std::ofstream ch("ch_out.txt");
std::ostream_iterator< Point_2 > out( "p ", ch, "\n" );
CGAL::ch_graham_andrew( in_start, in_end, out );
and the problem is that I do not want/can touch the CGAL function.
You have to overload the operator<< for the std::ostream class, so that it "knows" how to print an instance of your custom class.
Here is a minimal example of what I understand you want to accomplish:
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
class MyClass {
private:
int x_;
int y_;
public:
MyClass(int x, int y): x_(x), y_(y) {}
int x() const { return x_; }
int y() const { return y_; }
};
std::ostream& operator<<(std::ostream& os, const MyClass &c) {
os << "p " << c.x() << " " << c.y();
return os;
}
int main() {
std::vector<MyClass> myvector;
for (int i = 1; i != 10; ++i) {
myvector.push_back(MyClass(i, 2*i));
}
std::ostream_iterator<MyClass> out_it(std::cout, "\n");
std::copy(myvector.begin(), myvector.end(), out_it);
return 0;
}