function that may work in-place - c++

I have the following function:
shared_ptr_of_points filter(const shared_ptr_of_points input){
shared_ptr_of_points result = make_new();
for(const auto item:input->points){
if(cond(item)){
result->add_point(item);
}
}
return result;
}
A typical use is:
auto filtered_points = filter(some_noisy_points);
However, it may be used in another way which is:
some_points = filter(some_points);
The above implementation works fine in this case. However, an unnecessary copy is done.
The question: What is the classical solution for this problem?
P.S. I need both cases to work fine where in the first one, the copy should happen (I have to accept the argument as const). In the second case, no copy should happen.
While overloading is OK, making two separated functions is not an option.

You could achieve your goal nicely by using a slightly different prototype:
void filter(const shared_ptr_of_points & input, shared_ptr_of_points & output)
If you are willing to use it, then a possible implementation will look like this:
// Example program
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <algorithm>
typedef std::shared_ptr<std::vector<int>> shared_ptr_of_points;
bool cond(int x){
return x > 100;
}
void filterCopy(const shared_ptr_of_points & input, shared_ptr_of_points & output){
if (!output){
output = std::make_shared<std::vector<int>>();
}
for(const auto item:*input){
if(cond(item)){
output->push_back(item);
}
}
}
void filterInplace(shared_ptr_of_points & inout){
inout->erase(std::remove_if(inout->begin(), inout->end(), [](int x){return !cond(x);}), inout->end());
}
void filter(const shared_ptr_of_points & input, shared_ptr_of_points & output){
if (output == input)
filterInplace(output);
else
filterCopy(input, output);
}
int main()
{
shared_ptr_of_points pts = std::make_shared<std::vector<int>>();
pts->emplace_back(100);
pts->emplace_back(200);
pts->emplace_back(300);
for(const auto item:*pts){
std::cout << item << std::endl;
}
std::cout << "**********" << std::endl;
shared_ptr_of_points resCopy;
filter(pts, resCopy);
for(const auto item:*resCopy){
std::cout << item << std::endl;
}
std::cout << "**********" << std::endl;
filter(pts, pts);
for(const auto item:*pts){
std::cout << item << std::endl;
}
}

Related

C++ function map with varialbles input

In C++, I want to use a map of functions with different type of input or output.
Do to so, I found that using a map with any type could be a way.
But I get several problems. First, I can not use directly the functions in the map.
However, I can use a lambda function to wrap the functions then use these lambda functions in the map.
But, I get a second problem, I still need to cast with the lambda function which is not a variable. This makes a use from a string variable complicated.
Here is a MWE:
#include <any>
#include <functional>
#include <iostream>
#include <map>
#include <string>
void funct0()
{
std::cout << "funct0" << std::endl;
}
void funct1(int p)
{
std::cout << "funct1 " << p << std::endl;
};
int funct2(int p, std::string s)
{
std::cout << "funct2 " << s << std::endl;
return p+1;
};
float funct3(int a, float b)
{
std::cout << "funct3 " << std::endl;
return a +b;
}
auto funct4(int a, float b)
{
std::cout << "funct4 " << std::endl;
std::vector<float> v;
v.push_back(a);
v.push_back(b);
return v;
}
int main()
{
std::map<std::string, std::any> mapFunct;
mapFunct["F0"]= funct0;
// mapFunct["FO"](); // error: no match for call to ‘(std::map<std::__cxx11::basic_string<char>, std::any>::mapped_type {aka std::any}) ()’
mapFunct["F1"]= funct1;
// mapFunct["F1"](12); // error: no match for call to ‘(std::map<std::__cxx11::basic_string<char>, std::any>::mapped_type {aka std::any}) (int)’
// WHY THIS IS NOT WORKING ?
// From this link: https://stackoverflow.com/questions/61969316/is-it-possible-to-put-lambda-expressions-into-a-map-or-list-in-c
auto lambda0 = [](){funct0();};
auto lambda1 = [](int p) { funct1(p); return p; };
auto lambda2 = [](int p, std::string s) { return funct2(p,s); };
auto lambda3 = [](int a, float b){return funct3(a,b);};
auto lambda4 = [](int a, float b){return funct4(a,b);};
std::map<std::string, std::any> mapLambda;
mapLambda["L0"]=lambda0;
mapLambda["L1"]=lambda1;
mapLambda["L2"]=lambda2;
mapLambda["L3"]=lambda3;
mapLambda["L4"]=lambda4;
std::any_cast<decltype(lambda0)>(mapLambda["L0"])();
std::any_cast<decltype(lambda1)>(mapLambda["L1"])(2);
std::cout << std::any_cast<decltype(lambda2)>(mapLambda["L2"])(4, "HELLO") << std::endl;
std::cout << std::any_cast<decltype(lambda3)>(mapLambda["L3"])(3, 4.32) << std::endl ;
auto vec4= std::any_cast<decltype(lambda4)>(mapLambda["L4"])(6, 9.1);
std::cout << "vec4" << vec4[1] << vec4[2] << std::endl ;
std::vector<std::string> inputString;
inputString.push_back("L3(3, 4.32)");
inputString.push_back("L4(6, 9.1)");
// Using a for loop with iterator
for(auto it = std::begin(inputString); it != std::end(inputString); ++it) {
std::cout << *it << "\n";
std::string line=*it;
std::string functionInput = line.substr( 0, line.find("(") );
std::cout << functionInput << std::endl;
// argumentsInput= ;
mapLambda[functionInput](argumentsInput);
}
};
So my question are:
Why my example is working with lambda functions and not the functions ?
How can I make the last part of my example works only from the inputString variable? (ie, knowing the correct casting from the string variable)
What you probably want is something like this:
using CallWrapper = std::function<void(const std::string&)>;
std::map<std::string, CallWrapper> mapLambda;
mapLambda["L0"] = [funct0](const std::string&) { funct0(); };
mapLambda["L1"] = [funct1](const std::string& args) {
int p = ...; // parse the argument from `args`
funct1(p);
};
mapLambda["L2"] = [funct2](const std::string& args) {
// parse the arguments from `args`
int p = ...;
std::string s = ...;
funct2(p, s);
};
Now you can run the loop you envision:
for(const std::string& line : inputString) {
size_t pos = line.find('(');
std::string functionInput = line.substr( 0, pos);
std::string argumentsInput = line.substr(pos);
mapLambda[functionInput](argumentsInput);
}
The hard part, of course, is "parse the arguments from args", left as an exercise for the reader.
std::any_cast needs to cast to constructible types. A standard C++ function is neither a type nor constructible (it's just a group of statements given a name [edit: this isn't technically true, but what's going on under the hood is fairly complicated]), but std::function is. One way to get around this is to assign a standard C++ function to an std::function. Here's an example using a std::map like you were using:
#include <any>
#include <functional>
#include <iostream>
#include <map>
int my_func(int val) { return val + 1; }
std::function<int(int)> f = my_func;
int main() {
auto my_map = std::map<std::string, std::any>();
my_map["func"] = f;
std::cout << std::any_cast<std::function<int(int)>>(my_map["func"])(13) << std::endl; // prints "14"
return 0;
}
Lambdas are constructible types, which is why your code works for lambdas.
To answer your second question: I don't think it's possible. Functions with different signatures are different types, and you have to know what you're casting to. std::function<int(int, string)> and std::function<float(int, float)>, for example, are different types.
Also, the intended purpose of lambdas is to be used once then discarded. If you're going to keep lambdas around for reuse, it's better to simply just use functions.

Is it possible to put lambda expressions into a map or list in C++?

#DanielLangr #luxun #cdhowie sorry for the XY problem. i am not sure i can explain well, but i try my best. the situation is almost like this: there is a base object "Worker" and some children. chef、tailor... children has the same action like walk、run、sleep...but different skill,chef can make food, tailor can Make clothes. Invoker call Worker dothings but do not exactly know their profession.so i add a interface dothings(Thing) on Worker the base object. Thing is an enum,value is MakeFood、MakeClothes...
Worker *w = new Chef();
w->dothings(MakeFood);//
w->dothings(MakeClothes);//throw exception "w do not have skill"
so i think meybe use a container in children that describe what it can do and how to do.
hope i explained clearly.and is there a better solution?
I want to put different lambda expressions into a list or Qmap, like below.
Qmap<String, lambda> map;
map.insert("first",[](int i) -> int {return i;});
map.insert("second",[](string s) -> string {return s;});
Is it possible in C++? And what is the type of lambda?
It is possible but using function wrapper.
For example,
std::map<std::string, std::function<void(std::string)>> my_map;
my_map.emplace("first", [](std::string i) { std::cout << i << std::endl; });
However, if you want to pass any type of argument to your function and return any type from your lambda/function, use boost::any. You also use std::any if you are using C++17 or above.
EDIT:
A working example:
#include <iostream>
#include <string>
#include <functional>
#include <map>
#include <boost/any.hpp>
int main()
{
auto any = [](boost::any i)
{
std::cout << "In any" << std::endl;
if (i.type() == typeid(int))
std::cout << boost::any_cast<int>(i) << std::endl;
return boost::any(1000);
};
std::map<std::string, std::function<boost::any(boost::any)>> my_map;
my_map.emplace("first", any);
my_map.emplace("second", [](boost::any i) -> boost::any { });
auto ret = my_map["first"](100);
std::cout << boost::any_cast<int>(ret) << std::endl;
return 0;
}
Outputs:
In any
100
1000
With any, the solution may look like as follows:
auto lambda1 = [](int i) { return i; };
auto lambda2 = [](std::string s) { return s; };
std::map<std::string, std::any> map;
map["first"] = lambda1;
map["second"] = lambda2;
std::cout << std::any_cast<decltype(lambda1)>(map["first"])(-1) << std::endl;
std::cout << std::any_cast<decltype(lambda2)>(map["second"])("hello") << std::endl;
I am not familiar with Qmap and String, so I used the types from the C++ Standard Library.
Live demo: https://godbolt.org/z/8XK8de
Alternatively, you can also additionally use std::function if you want to avoid those decltypes:
std::map<std::string, std::any> map;
map["first"] = std::function<int(int)>( [](int i) { return i; } );
map["second"] = std::function<std::string(std::string)>( [](std::string s) { return s; } );
std::cout << std::any_cast<std::function<int(int)>>(map["first"])(-1) << std::endl;
std::cout << std::any_cast<std::function<std::string(std::string)>>(map["second"])("hello") << std::endl
Live demo: https://godbolt.org/z/XAc3Q2
However, as other pointed out to, this really seems to be an XY problem.
It is possible as long as you are trying to insert the same lambda type ( your example has different lambda types) You have to be careful how you do it but it does work. For example
#include <iostream>
#include <map>
int main(){
auto factory = [](int i){
return [=](int j){return i+j;};
};
using L = decltype(factory(0));
std::map<int,L> map;
map.emplace(0,factory(0));
map.emplace(7,factory(7));
std::cout << map.at(0)(3) << std::endl ;
std::cout << map.at(7)(3) << std::endl ;
}
outputs
3
10
as expected and not a std::function in sight! However the following does not work
#include <iostream>
#include <map>
int main(){
auto factory = [](int i){
return [=](int j){return i+j;};
};
using L = decltype(factory(0));
std::map<int,L> map;
map[0]=factory(0);
map[7]=factory(7);
std::cout << map[0](3) << std::endl ;
std::cout << map[7](3) << std::endl ;
}
Using the indexing operator tries to use copy assignment whereas emplace doesn't.
https://godbolt.org/z/co1vno6xb

Making reversed output using vector, stl

I read data from a text file named test.txt. File contents:
C++ is disturbing me every day
and i want a result like,
++C si gnibrutsid yreve yad (reversed words)
is me C++ day every disturbing (sorted based on length)
How can I do it? Here's what I have tried:
#include <fstream>
#include <iostream>
#include <vector>
using namesapce std;
string file { "test.txt" }
int main()
{
ifstream in(file);
vector<char> v{istreambuc_iterator<char>(in), istreambuf_iterator < char()};
/* my horrible coding
int n{ 0 };
for (auto i = v.cbegin(); i < v.cend(); ++i)
{
int tmp=0;
if (*i == ' ')
{
v[n] = tmp;
v[n] = *i;
tmp = *i;
}n++;
}
--------------------*/
for (auto c : v) cout << c;
}
Read each word individually, and then do whatever processing you want:
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
void printReversedWords(std::vector<std::string> const& vec) noexcept {
for (auto const& str : vec) {
std::copy(str.crbegin(), str.crend(),
std::ostream_iterator<char>(std::cout));
std::cout << ' ';
}
std::cout << '\n';
}
// remove noexcept if you care catching bad_alloc
void printSortedVec(std::vector<std::string> const& vec) noexcept {
auto const vec_view = [&vec] {
std::vector<std::string const*> vec_view;
vec_view.reserve(vec.size());
std::transform(vec.cbegin(), vec.cend(), std::back_inserter(vec_view),
[](auto const& str) { return &str; });
std::sort(vec_view.begin(), vec_view.end(),
[](auto const* const pstr1, auto const* const pstr2) {
return pstr1->size() < pstr2->size();
});
return vec_view;
}(); // IILE
for (auto const* const pstr : vec_view) std::cout << *pstr << ' ';
std::cout << '\n';
}
int main() {
auto constexpr fileName = "./test.txt";
std::ifstream in(fileName);
if (!in) {
std::cerr << "Failed to open the file";
return -1;
}
std::vector<std::string> const vec{ std::istream_iterator<std::string>(in), {} };
printReversedWords(vec);
printSortedVec(vec);
}
You can use C++ build in algorithms.
First see the example code, which could give you and idea on how it could be implemented:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>
const std::string fileName{ "test.txt" };
int main() {
// Open the file and check, if it could be opened.
if (std::ifstream inStream(fileName); inStream) {
// Read all words from the file into our vector
std::vector words(std::istream_iterator<std::string>(inStream), {});
std::cout << "\nReversed words:\n\n";
// Show reversed words
std::transform(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, " "),
[](const std::string& s) { return std::string(s.rbegin(), s.rend()); });
// Sort
std::sort(words.begin(), words.end());
// Show sorted list of words
std::cout << "\n\n\nSorted list of words:\n\n";
std::copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, " "));
std::cout << "\n\n";
}
else {
std::cerr << "\n*** Error: Could not open file: " << fileName << "\n\n";
}
return 0;
}
First, we open the file and check, if open was successful. This we do with the if with init statement. So we prevent pollution of the outer namespace. The stream variable is just used within the if-statement. And by using the init part of the if-statement, we will open the file. The condition part of the if-statement is just the stream variable. And this will work, because the bool operator of the ios::stream is overloaded and will return, if the file stream is ok or not.
OK, now the file is open, and we wan to read all words. So, we define a std::vector named "words". There is no need to define the template parameter of the std::vector. With C++17 CTAD (Class Template Argument Deduction), because it will be deduced automatically.
We use the range constructor of the std::vector (here number 5). The begin iterator is the std::istream_iterator. It will call the extractor operator >> until all input is consumed. Please note. We do not need to explicitly mention the end iterator, since the {} will be used as default initializer. Please see here: constructor number 1.
So, be defining the variable and using its range constructor, we will read all words from the file.
For reversing the words, we will also use the range constructor of the std::sting. And as begin and end iterator we use the reversed versions. So, very simple.
And to show the reversed strings, we will use std::transform, go over all words, put it into the std::ostream_operator. This will call the inserter operator << for all words. And the transformation function is a Lambda, that returns the reversed string.
Sorting is trivial and also copying the sorted words to std::cout is rather simple.
All this results in elegant and modern C++ code, with only a few lines.

MessagePack C++ - How to iterate through an unknown data structure?

I want to share structured data between C++ and Python languages using MessagePack like this one:
{
"t" : [ [t00,...,t0N], ... , [tM0,...,tMN] ],
"x" : [ x0,..,xN],
"P" : [ [P00, ..., P0N], ..., [PM0,...,PMN] ]
}
The number of variables is optional so in some cases I will have for example only:
{
"t" : [ [t00,...,t0N], ... , [tM0,...,tMN] ]
}
Decoding this in Python is pretty simple, my problem is to figure out
how to decode this in C++ if I don't know in advance the structure of
the data ? or the exact number of variables that I would have; is it
possible to iterate the structure in these cases?
I managed to handle a "fixed" data structure ( always with the same
number of variables ) defining a struct for example:
struct variables
{
std::vector< std::vector<double> > t;
std::vector< double > x;
std::vector< std::vector<double> > P;
MSPACK_DEFINE_MAP( t, x, P );
};
std::stringstream inBuffer;
.... (read data )
std::string str( inBuffer.str() );
msgpack::object_handle oh = msgpack::unpack( str.data(), str.size() );
msgpack::object deserialized = oh.get();
variables var;
deserialized.convert( var );
Is there a better way to accomplish this ?, how could manage optional
variables that could not appear in the structure ?; I repeat the
previous question: could I iterate an unknown data structure in C++?,
how ?
Thanks in advance!
Regards, Ernesto
There are two ways to treat unknown data structure.
The first way is using parse/visitor mechanism.
Here is an example:
#include <msgpack.hpp>
#include <sstream>
#include <iostream>
// This is a simple print example visitor.
// You can do any processing in your visitor.
struct my_visitor : msgpack::null_visitor {
bool start_map_key() {
processing_map_key = true;
return true;
}
bool end_map_key() {
processing_map_key = false;
return true;
}
bool start_array(uint32_t size) {
std::cout << "array (size:" << size << ")[" << std::endl;
return true;
}
bool end_array() {
std::cout << "]" << std::endl;
return true;
}
bool visit_str(const char* v, uint32_t size) {
if (processing_map_key) {
std::cout << "map key:" << std::string(v, size) << std::endl;
}
return true;
}
bool visit_positive_integer(uint64_t v) {
std::cout << "found value:" << v << std::endl;
return true;
}
bool processing_map_key = false;
std::string indent;
};
int main() {
// create test data
std::stringstream ss;
msgpack::packer<std::stringstream> pk(ss);
pk.pack_map(1);
pk.pack("t");
pk.pack_array(2);
pk.pack_array(3);
pk.pack(1);
pk.pack(2);
pk.pack(3);
pk.pack_array(3);
pk.pack(4);
pk.pack(5);
pk.pack(6);
// print data (for debug)
{
auto oh = msgpack::unpack(ss.str().data(), ss.str().size());
std::cout << oh.get() << std::endl;
}
// apply visitor
{
my_visitor mv;
msgpack::parse(ss.str().data(), ss.str().size(), mv);
}
}
Running demo: https://wandbox.org/permlink/3NrR4IMDIuLTk9e9
See https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_visitor.
The other way is using msgpack::type::variant or `msgpack::type::variant_ref.
The former copies data, you can update it. The latter doesn't copy data. You cannot update it.
This approach requires boost. So you need to define MSGPACK_USE_BOOST. I recommend defining as a compiler option.
// Boost is required
#define MSGPACK_USE_BOOST
#include <msgpack.hpp>
#include <sstream>
#include <iostream>
struct my_visitor:boost::static_visitor<void> {
void operator()(uint64_t v) const {
std::cout << "positive insteger:" << v << std::endl;
}
// const is required for map key because std::multimap's key (first) is const.
void operator()(std::string const& v) const {
std::cout << "string:" << v << std::endl;
}
void operator()(std::vector<msgpack::type::variant>& v) const {
std::cout << "array found" << std::endl;
for (auto& e : v) {
boost::apply_visitor(*this, e);
}
}
void operator()(std::multimap<msgpack::type::variant, msgpack::type::variant>& v) const {
std::cout << "map found" << std::endl;
for (auto& e : v) {
std::cout << "key:" << std::endl;
boost::apply_visitor(*this, e.first);
std::cout << "value:" << std::endl;
boost::apply_visitor(*this, e.second);
}
}
template <typename T>
void operator()(T const&) const {
std::cout << " match others" << std::endl;
}
};
int main() {
// create test data
std::stringstream ss;
msgpack::packer<std::stringstream> pk(ss);
pk.pack_map(1);
pk.pack("t");
pk.pack_array(2);
pk.pack_array(3);
pk.pack(1);
pk.pack(2);
pk.pack(3);
pk.pack_array(3);
pk.pack(4);
pk.pack(5);
pk.pack(6);
auto oh = msgpack::unpack(ss.str().data(), ss.str().size());
std::cout << oh.get() << std::endl;
msgpack::type::variant v = oh.get().as<msgpack::type::variant>();
boost::apply_visitor(my_visitor(), v);
}
Running demo: https://wandbox.org/permlink/HQwJjfwW8rLEMi0d
See https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_variant
Here are exampless:
https://github.com/msgpack/msgpack-c/blob/master/example/boost/msgpack_variant_capitalize.cpp
https://github.com/msgpack/msgpack-c/blob/master/example/boost/msgpack_variant_mapbased.cpp
Both ways can treat unpredictable data structure. You need to do some visitor processing. If the data structure is predictable some extent, your original approach is also good way.
Actually there is a simpler way, if you are dealing with maps (like stated in the question), not arrays.
msgpack::object_handle oh = msgpack::unpack(/* some data */);
std::map<std::string,msgpack::type::variant> map = obj.convert();
This way you will get a map with all the data, no need for a visitor or boost.

Sort std::vector<myclass> in one line using sort function from STL

Question is about sorting std::vector<myclass> using function sort from STL's algorithms class.
Standard way is : sort(v.begin(), v.end(), &myfunct)
where myfunct is:
bool myfunct( myclass first, myclass second ) {
if (first.value < second.value)
return true;
else return false;
}
Approach above takes more than one line. I am curious how to do it in one line. Is it possible define function that compares myclass objects inside sort function? May be somehow use this (a < b) ? a : b. I remember that there is something like this in C#, but I forgot how is it called. Is it possible to do in C++.
First, you can just return first.value < second.value but this doesn't get rid of the function. In C++2011 you can use a lambda function:
std::sort(begin, end, [](myclass const& f, myclass const& s){ return f.value < s.value; });
Without C++2011 I think you'll need a function object because there isn't anything which projects your class to the value you actually want to compare.
BTW, you definitely want to pass everything but the most trivial objects by reference to your comparison function.
You could use boost::lambda and boost::lambda::bind (with boost lambda placeholders)
std::sort(vec.begin(), vec.end(),
boost::lambda::bind(&A::a, boost::lambda::_1)
<
boost::lambda::bind(&A::a, boost::lambda::_2));
sort passes 2 values to the comparison function so you need to compare those 2 values. The bind part of code just selects variable a from the struct A from each structures being compared (referenced by _1 and _2).
Example code:
#include <iostream>
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/array.hpp>
struct A
{
A() : a(0), b(0) {}
int a;
int b;
};
std::ostream & operator<<(std::ostream & os, A & a)
{ return os << a.a << ":" << a.b; }
int main()
{
boost::array<A,5> vec;
std::fill(vec.begin(),vec.end(),A());
vec[0].a = 1;
vec[1].a = 3;
vec[2].a = 4;
vec[3].a = 0;
vec[4].a = 2;
std::for_each(vec.begin(),vec.end(), std::cout << boost::lambda::_1 << ' ');
std::cout << std::endl;
std::sort(vec.begin(), vec.end(),
boost::lambda::bind(&A::a, boost::lambda::_1)
<
boost::lambda::bind(&A::a, boost::lambda::_2));
std::for_each(vec.begin(),vec.end(), std::cout << boost::lambda::_1 << ' ');
std::cout << std::endl;
}
Output:
1:0 3:0 4:0 0:0 2:0
0:0 1:0 2:0 3:0 4:0
why not copy the vector into a set:
std::copy(v.begin(),v.end(),std::inserter(s,s.end()));
Now the elements in the set are sorted in ascending order and use set now.
A one liner call to sort() : sort(my_vector_of_class_object.begin(),my_vector_of_class_object.end(),compare);
Code of a working demo of a "sort vector of class objects" is provided below:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class my_Class
{
public:
my_Class(int r,int n, int s):rollno(r),name(n),status(s) { }
int getRollno() const { return rollno;}
int getName() const { return name;}
int getStatus() const { return status;}
private:
int rollno;
int name;
int status;
};
bool compare(const my_Class& x, const my_Class& y) {
return x.getRollno() < y.getRollno();
}
int main()
{
vector<my_Class> my_vector_of_class_object;
vector<my_Class>::const_iterator iter;
my_Class s1(10,20,30);
my_Class s2(40,50,60);
my_Class s3(25,85,9);
my_Class s4(1,50,2);
my_Class s5(90,70,90);
my_Class s6(85,85,3);
my_Class s7(20,6,89);
my_Class s8(70,54,22);
my_Class s9(65,22,77);
my_vector_of_class_object.push_back(s1);
my_vector_of_class_object.push_back(s2);
my_vector_of_class_object.push_back(s3);
my_vector_of_class_object.push_back(s4);
my_vector_of_class_object.push_back(s5);
my_vector_of_class_object.push_back(s6);
my_vector_of_class_object.push_back(s7);
my_vector_of_class_object.push_back(s8);
my_vector_of_class_object.push_back(s9);
cout <<"Before vector sort \n";
for(iter=my_vector_of_class_object.begin(); iter!=my_vector_of_class_object.end();++iter)
std::cout << (*iter).getRollno() << '\t' << (*iter).getName() << '\t' << (*iter).getStatus() << '\n';
cout <<" \n\n";
sort(my_vector_of_class_object.begin(),my_vector_of_class_object.end(),compare);
cout <<"After vector sort \n";
for(iter=my_vector_of_class_object.begin(); iter!=my_vector_of_class_object.end();++iter)
std::cout << (*iter).getRollno() << '\t' << (*iter).getName() << '\t' << (*iter).getStatus() << '\n';
cout <<" \n\n";
return 0;
}