I've found myself writing
for(int i=0;i<myvec.size();i++)
myvec[i]->DoWhatever(param);
a lot, and I'd like to compress this into a foreach statement, but I'm not sure how to get param in there without going super-verbose. I've also got things like
for(int i=0;i<myvec.size();i++)
if(myvec[i]->IsOK())
myvec[i]->DoWhatever(param);
and I'd like to rewrite that guy too. Any thoughts?
Oh, also, for various reasons, I don't want to use boost.
#include <vector>
#include <algorithm>
#include <functional>
class X
{
public:
void doWhat(int x) {}
bool IsOK() const {return true;}
};
class CallWhatIfOk
{
public:
CallWhatIfOk(int p): param(p) {}
void operator()(X& x) const
{ if (x.IsOK()) {x.doWhat(param);}}
private:
int param;
};
int main()
{
std::vector<X> myVec;
std::for_each( myVec.begin(),
myVec.end(),
std::bind2nd(std::mem_fun_ref(&X::doWhat),4)
);
std::for_each( myVec.begin(),
myVec.end(),
CallWhatIfOk(4)
);
}
Oh, also, for various reasons, I don't want to use boost.
Valid decision, but most likely the wrong one. Consider Boost as an extension to the STL. C++ is a library-driven language. If you don't take this into account, your code will be qualitatively inferior.
While std::for_each can be used here, the absence of lambda expressions in C++ until C++0x makes this tedious. I advocate using Boost.ForEach! It makes this much easier:
foreach (yourtype x, yourvec)
if (x.IsOK())
x.Whatever();
My preferred solution is usually to write a functor to do what I need:
struct doWhatever {
doWhatever(const Param& p) p(p) {}
void operator(MyVec v&, Param p) {
v.DoWhatever(param);
}
private:
Param p;
};
And then the loop:
std::for_each(myvec.begin(), myvec.end(), doWhatever(param));
Depending on how many variations of this you have, this might be a bit too verbose.
There are plenty of options for doing it inline though.
boost::lambda would let you construct the function you need at the call-site. boost::bind (or the standard library bind functions) would let you bind the parameter param to the function so you don't need to supply it as an argument every time.
boost::lambda is probably the most concise and flexible approach. I usually use the plain functor approach because the syntax is easier to remember. ;)
well when we have compilers that support C++0x lambda expresions, this becomes straightforward and minimally invasive:
std::for_each(myvec.begin(),myvec.end(),[&](X& item){
item->DoWhatever(param);
});
and the second example may look like this:
std::for_each(myvec.begin(),myvec.end(),[&](X& item){
if(item->IsOK())
myvec[i]->DoWhatever(param);
});
#include <vector>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/lambda/if.hpp>
#include <boost/lambda/bind.hpp>
struct A
{
bool IsOK () { return true; }
void DoWhatever (int param) {}
};
struct B
{
bool IsOk (A * a) { return true; }
void DoWhatever (A * a, int param) {}
};
typedef std::vector<A *> Myvec;
void main()
{
Myvec myvec;
int param = 1;
B b;
// first challenge using boost::bind (fnct in the same class)
std::for_each (myvec.begin(), myvec.end(),
boost::bind (&A::DoWhatever, _1, param));
// first challenge using boost::bind (fnct in an external class)
std::for_each (myvec.begin(), myvec.end(),
boost::bind (&B::DoWhatever, &b, _1, param));
// second challange using boost::lambda (fnct in the same class)
std::for_each (myvec.begin(), myvec.end(),
boost::lambda::if_then(
boost::lambda::bind (&A::IsOK, boost::lambda::_1),
boost::lambda::bind (&A::DoWhatever, boost::lambda::_1, param)
)
);
// second challange using boost::lambda (fnct in an external class)
std::for_each (myvec.begin(), myvec.end(),
boost::lambda::if_then(
boost::lambda::bind (&B::IsOK, &b, boost::lambda::_1),
boost::lambda::bind (&B::DoWhatever, &b, boost::lambda::_1, param)
)
);
}
You can simplify it by using namespaces...
If you are using GCC you can define something like:
#define foreach(element, array) \
for(typeof((array).begin()) element = (array).begin(), __end_##element = (array).end();\
element != __end_##element;\
++element)
and use it after like this:
foreach(element, array){
element->DoSomething(); //or (*element)->DoSomething() if type is already a pointer
}
I use this on a custom array but it works fine with std::vector too.
Related
I want to solve the following problem: I have a system of equations
ax+by=c
dx+ey=f
I have read in a tutorial that we can use a functor like the following
bool isIdd(int i){
return ((i%2)==1)
}
and than we can use this functor with the find_if function.
I want to ask if it is possible two return two values from a functor (for example a tuple) and can we use it with find_if STL function?
is possible to return two values from a functor (for example a tuple)
yes ,it is ,but you need also proper
operator bool()
As I understood, you want something like this:
#include <utility>
#include <algorithm>
#include <iterator>
#include <functional>
struct Pair{
bool b;
uint32_t data;
operator bool()const{
return this->b;
}
const Pair & isIdd(uint32_t p){
if (p == this-> data) this->b = true;
return *this ;
}
Pair(bool b , uint32_t data){
this-> b = b;
this->data = data;
}
};
int main(){
using namespace std::placeholders;
Pair p(0,0);
std::vector<uint32_t> vct {2};
auto it = vct.begin ();
auto b = std::bind(&Pair::isIdd,_1,_2);
std::find_if(vct.begin (),vct.end (),b(p,*it++ ));
}
But what is here is not relevant to the task set as the solution of the equation.
If this fits to you and you really want to use find_if as this ,turn it into template and somehow store found data.
I've been playing around a lot with the new C++11 lambda's, and the requirement to fully specify the template argument is a real drag. The syntax I would like to be using is something similar to the following:
#include <vector>
#include <algorithm>
struct foo
{
void bar() {}
};
int main()
{
vector<foo> v(10);
for_each(v.begin(), v.end(), [](f) {f.bar();});
^^^
}
Is there any way to get anything approximately close to this? Boost's Phoenix library is OK, but the syntax for calling member functions requires lots of boiler plate - I guess I'm after C++11's ease of calling member functions coupled with Phoenix's automatic deduction of type.
Current idea
I have gotten it down to this syntax:
vector<foo> x(1);
vector<bar> y(1);
for_each(x.begin(), x.end(), [](_a f) {f->f();});
for_each(y.begin(), y.end(), [](_a b) {b->b();});
Which works, but you have to add the capability per type (eg. ADD_AUTO_LAMBDA_SUPPORT(foo);). It also has the limitation that all supported types can not have any ambiguous members.
The full code for that is:
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
struct foo
{
foo() : x(3) {}
int x;
void f() { cout << x << endl;}
};
struct bar
{
bar() : y(133.7) {}
double y;
void b() { cout << y << endl;}
};
struct combo : foo, bar { };
struct _a
{
_a(foo& f) : offset(reinterpret_cast<combo*>(&f)) {}
_a(bar& b) : offset(reinterpret_cast<combo*>((char*)&b - 2*sizeof(foo))) {}
combo* operator->() { return offset; }
private:
combo* offset;
};
int main()
{
vector<foo> x(1);
vector<bar> y(1);
for_each(x.begin(), x.end(), [](_a f) {f->f();});
for_each(y.begin(), y.end(), [](_a b) {b->b();});
}
You could then use some template and preprocessor magic to generate both _a and combo, but the issue comes when you have ambiguous names (eg. a third struct with a b() function - you need a way to disambiguate them that I can't think of at the moment.
Note: I fully agree that [](auto f){ ... } would be very desirable!
While we don't have that, what about good old typedef? It just adds one line, is very "low-tech" and makes the lambda easy to read:
typedef const map<key_type, value_type>::value_type& λp_t;
for_each(m.begin(), m.end(), [&](λp_t x) {...});
You can use decltype:
for_each(m.begin(), m.end(), [&](decltype(*m.begin()) x){...});
But it really, really sucks that you cant use auto in anonymous lambdas.
Update:
You could also do
#define _A(CONTAINER_NAME) decltype(*CONTAINER_NAME.begin())
for_each(m.begin(), m.end(), [&](_A(m) x) { ... });
So, presumably in the case of the following:
std::array<int,10> a;
for_each(begin(a),end(a),[](auto i){ /* ... */ });
You want the compiler to figure out that the lambda takes an int and basically read this as:
for_each(begin(a),end(a),[](int i){ /* ... */ });
The issue is that the type of the lambda affects the type of the for_each template instantiation, which might choose a different specialization, which could in turn require a different type deduction for the lambda parameter. So there is simply no reasonable way for the compiler to use the algorithm code to automatically deduce the type of the arguments you pass in.
Anyway, at least for the for_each algorithm you don't need this, just use the range for loop:
for(auto i:a) { /* ... */ }
And in other places use decltype:
transform(begin(a),end(a),begin(a),[](decltype(*begin(a)) i) { return 2*i; });
You can have lambda deduce it parameters(and types) from the function, but then each function has to make that available. This discusses how that could be accomplished here:
http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/c347334187628476?hl=en
Basically you can call functions using a ruby-like way. So you would call for_each like this:
$(for_each(some_range), x)
{
printf("%i\n", x);
};
The ($) dollar sign is a macro that takes care of deducing the type from the function. Now this won't work with std::for_each, it has to be used with a specially defined function that emits the parameter types for the lambda.
Since it uses a macro it doesn't take into account operator precedence, so you can't use it with range adapters.
If you're willing to use macros and use all that setup wouldn't a shortcut macro using decltype be sufficient? Something like:
#define T_FOR_EACH( begin_, end_, var_, func_ ) \
for_each( (begin_), (end_), [](decltype(*begin_) var_) func_ )
Then you could have:
T_FOR_EACH(x.begin(), x.end(), &f, {f->f();} );
The reason I don't put & for the variable in the define is that with this format would can still specify all the type specifiers you want and whether it is a reference or copy.
Excuse me if the syntax is wrong, I don't have a C++11 compiler around I can test any of this with, it's just an idea.
So this compiles
#define FOR_EACH_IN(iter__, list__, ...) \
std::for_each(list__.begin(), list__.end(), [&](decltype(*list__.begin()) iter__) __VA_ARGS__)
Given:
auto DoSomethingTo = [](T AnElement){ /* insert profitable activity */ };
std::array<T, n> AnArray;
You can do:
FOR_EACH_IN(AnElement, AnArray,
{
DoSomethingTo(AnElement);
});
The JavaScript fanboy inside me is excited by how it looks but as a C++ coder I'm horrified to have come up with something like this. It's likely to trip lots of static analyses and linters, plus when something goes wrong I hope you enjoy debugging macros.
But, hey, it's clean.
I have a std::vector<A*> which I need to deep copy to another vector using A::Clone().
Instead of using handwritten loops, I was wondering whether I could use for_each or any Standard Library algorithm for this.
The appropriate algorithm is std::transform and you can turn member function invocation into a unary functor with std::mem_fun
Example:
#include <vector>
#include <functional>
#include <algorithm>
#include <iterator>
class X
{
public:
X* clone();
};
int main()
{
std::vector<X*> vec1, vec2;
std::transform(vec1.begin(), vec1.end(), std::back_inserter(vec2), std::mem_fun(&X::clone));
}
If the target vector is already the same size as the input range, you can pass vec2.begin() as the third argument. Use back_inserter if the target is empty (or you want to append to it).
Perhaps something like this would work:
class DeepCopy {
public:
A* operator() (A* aP) {
return aP->Clone();
}
}
int main()
{
vector<A*> vA;
vector<A*> vA2;
transform(vA.begin(), vA.end(), back_inserter(vA2), DeepCopy());
return 0;
}
You could use boost::ptr_vector<A> instead of std::vector<A*>.
This has a template parameter CloneAllocator, for which you could pass the relevant custom cloner.
Let's say I have the following object:
struct Foo
{
int size() { return 2; }
};
What's the best way (most maintainable, readable, etc.) to get the total size of all objects in a vector<Foo>? I'll post my solution but I'm interested in better ideas.
Update:
So far we have:
std::accumulate and a functor
std::accumulate and a lambda expression
plain ol' for-loop
Are there any other workable solutions? Can you make something maintainable using boost::bind or std::bind1st/2nd?
In addition to your own suggestion, if your compiler supports C++0x lambda expressions, you can use this shorter version:
std::vector<Foo> vf;
// do something to populate vf
int totalSize = std::accumulate(vf.begin(),
vf.end(),
0,
[](int sum, const Foo& elem){ return sum + elem.size();});
Use std::accumulate and a functor.
#include <functional>
#include <numeric>
struct SumSizes : public std::binary_function<int, Foo, int>
{
int operator()(int total, const Foo& elem) const
{
return total + elem.size();
}
};
std::vector<Foo> vf;
// do something to populate vf
int totalSize = std::accumulate(vf.begin(),
vf.end(),
0,
SumSizes());
I find Boost iterators elegants, although they can be a bit verbose (range-based algorithms would make this better). In this case transform iterators can do the job:
#include <boost/iterator/transform_iterator.hpp>
//...
int totalSize = std::accumulate(
boost::make_transform_iterator(vf.begin(), std::mem_fn(&Foo::size)),
boost::make_transform_iterator(vf.end(), std::mem_fn(&Foo::size)),0);
Edit: replaced "boost::bind(&Foo::size,_1)" by "std::mem_fn(&Foo::size)"
Edit: I just found that the Boost.Range library has been updated to introduce range algorithms! Here is a new version of the same solution:
#include <boost/range/distance.hpp> // numeric.hpp needs it (a bug?)
#include <boost/range/numeric.hpp> // accumulate
#include <boost/range/adaptor/transformed.hpp> // transformed
//...
int totalSize = boost::accumulate(
vf | boost::adaptors::transformed(std::mem_fn(Foo::size)), 0);
Note: the performances are approximately the same (see my comment): internally, transformed uses transorm_iterator.
using C++11 (and beyond) range-based for loop
std::vector<Foo> vFoo;
// populate vFoo with some values...
int totalSize = 0;
for (const auto& element: vFoo) {
totalSize += element.size();
}
Here is the down-to-earth solution:
typedef std::vector<Foo> FooVector;
FooVector vf;
int totalSize = 0;
for (FooVector::const_iterator it = vf.begin(); it != vf.end(); ++it) {
totalSize += it->size();
}
I developed a scripting engine that has many built-in functions, so to call any function, my code just went into an if .. else if .. else if wall checking the name but I would like to develop a more efficient solution.
Should I use a hashmap with strings as keys and pointers as values? How could I do it by using an STL map?
EDIT:
Another point that came into my mind: of course using a map will force the compiler not to inline functions, but my inefficient approach didn't have any overhead generated by the necessity of function calls, it just executes code.
So I wonder if the overhead generated by the function call will be any better than having an if..else chain.. otherwise I could minimize the number of comparisons by checking a character at runtime (will be longer but faster).
Whatever your function signatures are:
typedef void (*ScriptFunction)(void); // function pointer type
typedef std::unordered_map<std::string, ScriptFunction> script_map;
// ...
void some_function()
{
}
// ...
script_map m;
m.emplace("blah", &some_function);
// ...
void call_script(const std::string& pFunction)
{
auto iter = m.find(pFunction);
if (iter == m.end())
{
// not found
}
(*iter->second)();
}
Note that the ScriptFunction type could be generalized to std::function</* whatever*/> so you can support any callable thing, not just exactly function pointers.
In C++11 you can do something like this :
This Interface needs only the return type and it takes care of everything else from the caller side.
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <typeinfo>
#include <typeindex>
#include <cassert>
void fun1(void){
std::cout<<"inside fun1\n";
}
int fun2(){
std::cout<<"inside fun2\n";
return 2;
}
int fun3(int a){
std::cout<<"inside fun3\n";
return a;
}
std::vector<int> fun4(){
std::cout<<"inside fun4\n";
std::vector<int> v(4,100);
return v;
}
// every function pointer will be stored as this type
typedef void (*voidFunctionType)(void);
struct Interface{
std::map<std::string,std::pair<voidFunctionType,std::type_index>> m1;
template<typename T>
void insert(std::string s1, T f1){
auto tt = std::type_index(typeid(f1));
m1.insert(std::make_pair(s1,
std::make_pair((voidFunctionType)f1,tt)));
}
template<typename T,typename... Args>
T searchAndCall(std::string s1, Args&&... args){
auto mapIter = m1.find(s1);
/*chk if not end*/
auto mapVal = mapIter->second;
// auto typeCastedFun = reinterpret_cast<T(*)(Args ...)>(mapVal.first);
auto typeCastedFun = (T(*)(Args ...))(mapVal.first);
//compare the types is equal or not
assert(mapVal.second == std::type_index(typeid(typeCastedFun)));
return typeCastedFun(std::forward<Args>(args)...);
}
};
int main(){
Interface a1;
a1.insert("fun1",fun1);
a1.insert("fun2",fun2);
a1.insert("fun3",fun3);
a1.insert("fun4",fun4);
a1.searchAndCall<void>("fun1");
int retVal = a1.searchAndCall<int>("fun3",2);
a1.searchAndCall<int>("fun2");
auto temp = a1.searchAndCall<std::vector<int>>("fun4");
return 0;
}
You can also use Boost.Function and Boost.Bind what even allows you, to some degree, to have map of heterogeneous functions:
typedef boost::function<void, void> fun_t;
typedef std::map<std::string, fun_t> funs_t;
funs_t f;
void foo() {}
void goo(std::string& p) {}
void bar(int& p) {}
f["foo"] = foo;
f["goo"] = boost::bind(goo, "I am goo");
f["bar"] = boost::bind(bar, int(17));
It can be a map of functions of compatible prototypes as well, of course.
Above answers seem to give a complete overview, this regards only your second question:
Map element retrieval by key has O(log n) complexity. Hashmap retrieval by key has O(1) complexity + a little stuff on the side in case of collisions. So if theres a good hash function for your function names, use it. Your implementation will have a standard one. It should be fine.
But be aware, that anything below a hundred elements will not benefit all too much.
The only downside of a hash map is collision. In your case, the hashmap will be relatively static. You know the function names you support. So I advise you to create a simple test case, where you call unordered_map<...>::hash_function with all your keys to make sure that nothing collides. After that, you can forget about it.
A quick google for potential improvements on hash functions got me there:
A fiew good hash functions
Maybe, depending on your naming conventions, you can improve on some aspects of the function.
Well, you can use any_map to store functions with different signatures (but calling it will be messy) and you can use int_map to call functions with a specific signature (looks nicer).
int FuncA()
{
return 1;
}
float FuncB()
{
return 2;
}
int main()
{
// Int map
map<string,int(*)()> int_map;
int_map["A"] = FuncA;
// Call it
cout<<int_map["A"]()<<endl;
// Add it to your map
map<string, void(*)> any_map;
any_map["A"] = FuncA;
any_map["B"] = FuncB;
// Call
cout<<reinterpret_cast<float(*)()>(any_map["B"])()<<endl;
}
I've managed to modify the example from Mohit to work on member function pointers:
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <typeinfo>
#include <typeindex>
#include <cassert>
template <typename A>
using voidFunctionType = void (A::*)(void);
template <typename A>
struct Interface{
std::map<std::string,std::pair<voidFunctionType<A>,std::type_index>> m1;
template<typename T>
void insert(std::string s1, T f1){
auto tt = std::type_index(typeid(f1));
m1.insert(std::make_pair(s1,
std::make_pair((voidFunctionType<A>)f1,tt)));
}
template<typename T,typename... Args>
T searchAndCall(A a, std::string s1, Args&&... args){
auto mapIter = m1.find(s1);
auto mapVal = mapIter->second;
auto typeCastedFun = (T(A::*)(Args ...))(mapVal.first);
assert(mapVal.second == std::type_index(typeid(typeCastedFun)));
return (a.*typeCastedFun)(std::forward<Args>(args)...);
}
};
class someclass {
public:
void fun1(void);
int fun2();
int fun3(int a);
std::vector<int> fun4();
};
void someclass::fun1(void){
std::cout<<"inside fun1\n";
}
int someclass::fun2(){
std::cout<<"inside fun2\n";
return 2;
}
int someclass::fun3(int a){
std::cout<<"inside fun3\n";
return a;
}
std::vector<int> someclass::fun4(){
std::cout<<"inside fun4\n";
std::vector<int> v(4,100);
return v;
}
int main(){
Interface<someclass> a1;
a1.insert("fun3",&someclass::fun3);
someclass s;
int retVal = a1.searchAndCall<int>(s, "fun3", 3);
return 0;
}