There is example of code which generates N objects of class A on the heap:
#include <vector>
#include <iostream>
#include <algorithm>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
using boost::make_shared;
using boost::shared_ptr;
class A
{
int val_;
public:
explicit A(int i) : val_(i) {}
int foo() const { return val_;}
};
template<typename T>
struct Generator
{
shared_ptr<T> operator()()
{
return make_shared<T>(std::rand() % 10 + 1);
}
};
int main()
{
std::vector< shared_ptr<A> > coll;
std::generate_n( back_inserter(coll), 3, Generator<A>());
std::vector<shared_ptr<A> >::const_iterator cit;
for (cit = coll.begin(); cit != coll.begin(); ++cit)
std::cout << (*cit)->foo() << std::endl;
return 0;
}
Code uses functor "Generator" and "generate_n" algorithm to do the job. I wounder about simplification of this task. boost:lambda, boost::phoenix are possible candidates (if they are?), and how to do it? Or maybe there are other alternatives?
Simple would be not to convolute the problem in the first case:
std::vector< std::shared_ptr<A> > ints;
for ( int i = 0; i < 3; ++i )
ints.push_back( std::make_shared<A>( std::rand()%10 + 1 ) );
Each different paradigm has its strengths and weaknesses, and in this case, in C++, trying to force a functional approach to the problem will make things more complex than they need be.
With lambda support in the compiler you could do:
std::vector< shared_ptr<A> > coll;
std::generate_n( back_inserter(coll), 3, [](){
return std::make_shared<A>(std::rand()%10 + 1); });
Related
I am looking for a simple way to create an iterator for the values of a map in C++11.
This method should be simple and transparent: simple in that it should be easy to implement, and transparent in that the client should not know the values come from a map, not a set.
This question has been asked several times before. Many of these questions predate C++11 and use boost, which I do not want to use. Some are not simple, John Ahlgren's solution here, http://john-ahlgren.blogspot.com/2013/10/how-to-iterate-over-values-of-stdmap.html , for example requires a page of code to write a custom iterator.
The others are not transparent, i.e., clearly one can write:
map<string,foo> mymap;
for (auto it=mymap.begin();it!=mymap.end();++it){
Foo val= it->second;
...
}
However, I do not want to do this because I do not want the client to have to know of the data representation.
The problem comes up as follows.
I have a bunch of objects uniquely indexed with a long "key". Sometimes I want to manipulate sets of these objects. Other times I want to retrieve an object given its key.
I cannot use the "set" class directly for several reasons, chief among which is that it does not store mutable instances, and these instances must be mutable (except, obviously, for the key).
So, I have decided to store all my objects in a giant global hashtable:
map<long,Foo> all_the_objects;
I then do not work with set<Foo> at all. Instead I work with set<long> and use an adaptor to simulate a set of Foo, i.e.,
class SetOfFoo{
private: set<long> theKeys;
public:
void insert(const & Foo);
size_t size() return theKeys.size();
bool is_member(const & Foo)
{return theKeys.find(Foo.key)
!= theKeys.end;}
Foo & insert(const & Foo val){
long key=val.key;
all_the_objects[key]=val;
return all_the_objects[key];
}
...::iterator begin() {???}
}
In other words, the client of the SetOfFoo class does not know or need to know that SetOfFoo is implemented as as set of keys.
I also cannot just make a Vector myself in the adaptor class, because one cannot store references in C++ collections.
Is it really impossible to make a simple, transparent way to iterate over map<> values? I find it hard to believe, as this is a very common need and is trivial to do in every language I have seen that has hashtables. I just don't understand how this can be hard.
it's pretty trivial.
Here's an extremely simplistic version that minimally solves the problem for a map of ints to strings. You can either rewrite for the types you want or templatise it as you wish.
#include <map>
#include <iostream>
#include <iterator>
#include <string>
#include <algorithm>
struct map_value_iterator : public std::map<int, std::string>::const_iterator
{
map_value_iterator(std::map<int, std::string>::const_iterator src)
: std::map<int, std::string>::const_iterator(std::move(src))
{
}
// override the indirection operator
const std::string& operator*() const {
return std::map<int, std::string>::const_iterator::operator*().second;
}
};
using namespace std;
int main()
{
map<int, string> myMap { {1, "Hello" }, { 2, "World" } };
copy(map_value_iterator(begin(myMap)), map_value_iterator(end(myMap)), ostream_iterator<string>(cout , " "));
cout << endl;
return 0;
}
Program output:
Compiling the source code....
$g++ -std=c++11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1
Executing the program....
$demo
Hello World
You can do something like the following (C++98):
#include <iostream>
#include <map>
#include <string>
#include <algorithm>
#include "util/pair_iterator.hpp"
template<class T> inline T const& constify(T& t) { return t; }
int main()
{
using namespace std;
using namespace util;
map<int, string> m;
m[0] = "alice";
m[1] = "bob";
m[2] = "carol";
m[3] = "dave";
m[4] = "eve";
copy(
over_second(m.begin())
, over_second(m.end())
, ostream_iterator<string>(cout, "\n")
);
copy(
over_first(m.begin())
, over_first(m.end())
, ostream_iterator<int>(cout, "\n")
);
// const iterators check
copy(
over_second(constify(m).begin())
, over_second(constify(m).end())
, ostream_iterator<string>(cout, "\n")
);
copy(
over_first(constify(m).begin())
, over_first(constify(m).end())
, ostream_iterator<int>(cout, "\n")
);
}
Here is an implementation:
// util/pair_iterator.hpp
#include <iterator>
#include "boost/iterator/transform_iterator.hpp"
#include "boost/type_traits/remove_reference.hpp"
#include "boost/type_traits/is_const.hpp"
#include "boost/mpl/if.hpp"
namespace util {
namespace aux {
template<class T> struct dereference_type
: boost::remove_reference<typename std::iterator_traits<T>::reference>
{
};
template<class PairT>
struct first_extracter
{
typedef typename boost::mpl::if_<
boost::is_const<PairT>
, typename PairT::first_type const
, typename PairT::first_type
>::type result_type;
result_type& operator()(PairT& p) const { return p.first; }
};
template<class PairT>
struct second_extracter
{
typedef typename boost::mpl::if_<
boost::is_const<PairT>
, typename PairT::second_type const
, typename PairT::second_type
>::type result_type;
result_type& operator()(PairT& p) const { return p.second; }
};
} // namespace aux {
template<class IteratorT>
inline
boost::transform_iterator<aux::first_extracter<typename aux::dereference_type<IteratorT>::type>, IteratorT>
over_first(IteratorT const& i)
{
typedef aux::first_extracter<typename aux::dereference_type<IteratorT>::type> extracter;
return boost::transform_iterator<extracter, IteratorT>(i, extracter());
}
template<class IteratorT>
inline
boost::transform_iterator<aux::second_extracter<typename aux::dereference_type<IteratorT>::type>, IteratorT>
over_second(IteratorT const& i)
{
typedef aux::second_extracter<typename aux::dereference_type<IteratorT>::type> extracter;
return boost::transform_iterator<extracter, IteratorT>(i, extracter());
}
} // namespace util
I am trying to learn boost::phoenix and trying to use it in std::transform like below.
class myClass
{
int i;
public:
getNumber();
setNumber(int j);
};
int main()
{
std::vector<myClass*> vect
std::vector<int> numVect
numVect.resize(vect.size());
using boost::phoenix::arg_names::arg1;
std::transform (vect.begin(), vect.end(), numVect.begin(), arg1->getNumber());
}
But, I am getting an error error: base operand of '->' has non-pointer type 'const boost::phoenix::actor<boost::phoenix::argument<0> >'
I am not really sure what does it mean. Any help would be great. Thanks
As you note above, the way to do this with Phoenix is with phoenix::bind or with ->* as you do above:
#include <vector>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/range/algorithm/transform.hpp>
class myClass
{
int i;
public:
int getNumber() { return i; }
void setNumber(int j) { i = j; }
};
int main()
{
std::vector<myClass*> vect;
std::vector<int> numVect;
using boost::phoenix::arg_names::arg1;
boost::transform(vect,
std::back_inserter(numVect),
(arg1->*&myClass::getNumber)());
}
Phoenix can be complicated, and bind expressions are some of the most convoluted and contrived of Phoenix's syntactic contortions, but in all honestly, this one doesn't seem that bad.
C++14's polymorphic lambdas will obviate much of Phoenix, by the way.
I'd use
std::transform (vect.begin(), vect.end(), numVect.begin(), phx::bind(&myClass::getNumber, arg1));
Or, if you wanted nicer syntax:
auto getNumber = phx::lambda [ phx::bind(&myClass::getNumber, arg1) ];
std::transform (vect.begin(), vect.end(), numVect.begin(), getNumber(arg1));
Demo:
#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/phoenix/phoenix.hpp>
namespace phx = boost::phoenix;
struct myClass
{
int i;
int getNumber() const { return i; }
void setNumber(int j) { i = j; }
};
using namespace boost::phoenix::arg_names;
static const auto getNumber = phx::lambda [ phx::bind(&myClass::getNumber, arg1) ];
int main()
{
const std::vector<myClass*> vect { new myClass{1}, new myClass{2}, new myClass{42} };
std::vector<int> numVect(vect.size());
// puritan/standard version:
std::transform (vect.begin(), vect.end(), numVect.begin(), std::mem_fn(&myClass::getNumber));
// just bind:
std::transform (vect.begin(), vect.end(), numVect.begin(), phx::bind(&myClass::getNumber, arg1));
// using more natural syntax
std::transform (vect.begin(), vect.end(), numVect.begin(), getNumber(arg1));
for(auto i : numVect)
std::cout << i << " ";
}
Is there a nicer way of doing this
auto commodityOneLeg = boost::bind(&VegaFactory::load_commodity_one_leg,this,conn,_1);
std::map<std::string,decltype(commodityOneLeg)> methods;
methods.insert(std::make_pair("COMMODITYONELEG",commodityOneLeg));
methods.insert(std::make_pair("FXOPTION",boost::bind(&VegaFactory::load_fx_index,this,conn,_1)));
methods.insert(std::make_pair("FXBARROPT",boost::bind(&VegaFactory::load_fx_bar_opt,this,conn,_1)));
methods.insert(std::make_pair("COMMODITYINDEX",boost::bind(&VegaFactory::load_fx_index,this,conn,_1)));
auto f = methods.find(trade_table);
if(f != methods.end()) {
fx_opt = (f->second)(t_id);
}
Is there a way of declaring the type of std:map<> without having to declare a mapping first on the previous line? I guess I mean aesthetically - Code should look neat right?
Is there a cleaner/simpler way to do this c++ string switch statement overall when the input is a 'trade type' string.
Edit
To clarify further. I can manually write out the type of the boost:bind type but that seems excessive. And this is probably a really good example of where auto and decltype can be used to simplify the code.
However having to declare one entry in the map one way and the others in a different way just looks wrong; so that's what I want to address
IMHO using Boost.Signals2 is a more clear way. There is also the Boost.Signals library but it is deprecated starting from Boost 1.54. The following code demonstrates it. I think something similar is possible to implement using the Boost.Function library too.
#include <boost/signals2.hpp>
#include <map>
#include <string>
typedef boost::signals2::signal<bool (int)> CSignal;
typedef CSignal::slot_type CSignalSlotType;
typedef std::map<std::string, CSignalSlotType> CMethodMap;
bool Func1(int a, int b) {
return a == b;
}
bool Func2(int a, int b) {
return a < b;
}
int main(int, char *[]) {
CMethodMap methods;
methods.insert(std::make_pair("Func1", boost::bind(&Func1, 1, _1)));
methods.insert(std::make_pair("Func2", boost::bind(&Func2, 2, _1)));
auto it = methods.find("Func1");
if(it != methods.end()) {
CSignal signal;
signal.connect(it->second);
auto rt = signal(2);
if (rt) {
const bool result = *rt;
}
}
return 0;
}
Here is a sample code using the Boost.Function. It looks even simpler but I used to use the Signals2 library.
#include <map>
#include <string>
#include <boost/function.hpp>
#include <boost/bind.hpp>
typedef boost::function<bool (int)> CFunction;
typedef std::map<std::string, CFunction> CMethodMap;
bool Func1(int a, int b) {
return a == b;
}
bool Func2(int a, int b) {
return a < b;
}
int main(int, char *[]) {
CMethodMap methods;
methods.insert(std::make_pair("Func1", boost::bind(&Func1, 1, _1)));
methods.insert(std::make_pair("Func2", boost::bind(&Func2, 2, _1)));
auto it = methods.find("Func1");
if(it != methods.end()) {
auto &f = it->second;
const bool result = f(2);
}
return 0;
}
How do I make the code below only call the move-constructor once?
OUTPUT
MC
MC
CODE
#include <vector>
#include <map>
#include <memory>
#include <iostream>
struct Bar
{
Bar() { }
Bar( Bar&& rhs )
{
std::cerr << "MC\n";
for( auto& p : rhs.m_v )
{
std::cerr << "inside loop\n";
m_v.push_back( move( p ));
}
}
std::vector< std::unique_ptr< Bar >> m_v;
};
int main()
{
Bar b;
std::map<int,Bar> m;
m.insert( std::make_pair( 1, std::move( b )));
}
EDIT
It looks like emplace is the right answer - but unfortunately, it's not in gcc 4.7.2 yet... ...is there some way I can alias this to insert and then remove it when it's properly implemented?
Use std::map::emplace:
m.emplace(1, std::move(b));
Essentially by using emplace instead of insert:
m.emplace(1, std::move(b));
I have a list of Thing and a Controller that I want to notify() with each of the things. The code below works:
#include <algorithm>
#include <iostream>
#include <tr1/functional>
#include <list>
using namespace std;
class Thing { public: int x; };
class Controller
{
public:
void notify(Thing& t) { cerr << t.x << endl; }
};
class Notifier
{
public:
Notifier(Controller* c) { _c = c; }
void operator()(Thing& t) { _c->notify(t); }
private:
Controller* _c;
};
int main()
{
list<Thing> things;
Controller c;
// ... add some things ...
Thing t;
t.x = 1; things.push_back(t);
t.x = 2; things.push_back(t);
t.x = 3; things.push_back(t);
// This doesn't work:
//for_each(things.begin(), things.end(),
// tr1::mem_fn(&Controller::notify));
for_each(things.begin(), things.end(), Notifier(&c));
return 0;
}
My question is: can I get rid of the Notifier class by using some version of the "This doesn't work" line? Seems like I should be able to make something work, but can't quite get the right combination. (I've fumbled around with a number of different combinations.)
Without using boost? (I would if I could.) I'm using g++ 4.1.2, yes I know it is old...
You can accomplish this using bind, which is originally from Boost but is included in TR1 and C++0x:
using std::tr1::placeholders::_1;
std::for_each(things.begin(), things.end(),
std::tr1::bind(&Controller::notify, c, _1));
What about going old-school:
for(list<Thing>::iterator i = things.begin(); i != things.end(); i++)
c.notify(*i);