set of functors

Started by
5 comments, last by blewisjr 11 years, 4 months ago
I need a set of functors:


typedef std::function<void()> tFun;
std::set<tFun> sFun;

foo1 f1(5, "hello", 3.2f);
foo2 f2();
foo3 f3(4.5);
foo4 f4("doo", "daa");

sFun.insert(f1);
sFun.insert(f3);
sFun.insert(f2);
sFun.insert(f4);

auto it = sFun.begin();
const auto& end = sFun.end();

for(; it != end; ++it)
{
(*it)(); // call their operator ()
}


Error output:

error C2784: 'bool std::operator <(const std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::move_iterator<_RanIt> &' from 'const tFun'
....
.... blah, blah irrelevant
[/quote]

There is a problem with set's Compare "predicate" (or how is it called otherwise?) and i don't know how to go about this.

Thank you for your time.
Advertisement
The basic answer is you can't. std::function is not comparable. Not with less than and not with equality. You can store them in a sequence container if you wish, but there's no way to check if you already have a function already stored or not.
I got this with vector. Something like:


typedef std::function<void()> tFun;
std::vector<tFun> sFun;
...
void addFun(std::function<void()> f)
{
auto it = std::find_if(std::begin(sFun), std::end(sFun), [&f](const std::function<void()>& o){
return o.target_type() == f.target_type() ;
});
if(it == sFun.end())
sFun.push_back(f);
}
...
addFun(f1);
addFun(f2);
addFun(f3);
addFun(f1); // duplicate not added
addFun(f4);
addFun(f2);// duplicate not added
Careful, that may not do what you expect. If you have two function void foo(void) and void bar(void) and try to add both to your vector, they would look like duplicates to your addFun() function.
But will for for "classes only functors"? I will pass objects/functors not "pure" functions.

Thank you for help so far.
Yeah, even using function objects its possible to get situations where functions with different behaviors will look the same to that kind of test. Ex:

void foo(int i);

addFun(std::bind(&foo, 1));
addFun(std::bind(&foo, 2));

Here the two added functions will have the same type, but different behaviors.
It has been a while since I posted on this forum let alone dabbled in C++ but I can give this a shot.

I think the general gist is you are trying to be too fancy in your implementation. C++ is not really designed for function comparison. There is just not enough data to do so.

In this senario what I would do is keep it very simple. Not sure if this will work for what you want but what I would do is consider using a sort of key value hashtable data structure. One such example would be std::map. This will allow you to provide the extra data necessary to aquire the correct function when you need it. For the key you can use a descriptive name and for the value you can store a function pointer. I am not sure about std::function as I am a bit old on my C++ knowledge.

I appologize if this does not solve your issue but maybe it will give you a bit of a perspective to push you in the right direction.

This topic is closed to new replies.

Advertisement