0

I have a templated class Timer

template<typename Clock, typename Duration>
class Timer
{
public:
    void Register(const std::function<void(const std::chrono::time_point<Clock> &timePoint)> &eventHandler);

private:
    std::vector<std::function<void(const std::chrono::time_point<Clock> &timePoint)>> eventHandlers;

// Some more stuff.
};

Now I would like to find duplicate entries in Register and that's the problem.
I tried different approaches using std::find and a simple for loop.

The best I could get so far (removed namespaces for readability):

typename vector<function<void(const time_point<Clock> &timePoint)>>::iterator it;
for(it = eventHandlers.begin(); it != eventHandlers.end(); ++it)
{
}

My problem is to compare the parameter of Register with it.
I tried several things like:

typename function<void(const time_point<Clock> &timePoint)> &f = &(*it);
if(f == eventHandler)
{
    // Duplicate
}

... and some other more complicated approaches but none of them worked.
I have some trouble solving this as I usually code in C# and therefor I'm not used to do templating in C++.
How can I solve this and are there even more elegant solutions to this problem?

Edit:
I usually get this error:

binary '==': no operator found which takes a left-hand operand of type 'std::function<void (const std::chrono::time_point<std::chrono::system_clock,std::chrono::system_clock::duration> &)>' (or there is no acceptable conversion)
TorbenJ
  • 4,462
  • 11
  • 47
  • 84
  • 2
    The issue here isn't with templating, but with the fact that `std::function`s are [not equality comparable](http://stackoverflow.com/questions/3629835/why-is-stdfunction-not-equality-comparable). What does it mean for two things you pass into `Timer::Register` to be equal? – Claudiu Aug 24 '15 at 14:27

1 Answers1

1

Note:

typename function<void(const time_point<Clock> &timePoint)> &f = &(*it);
if(f == eventHandler)
{
    // Duplicate
}

I think you mean to put typename function<void(const time_point<Clock> &timePoint)> *f, as &(*it) returns a pointer type rather than a reference.


Update:

std::function is not == comparable, so you can do the following:

not use std::function but instead use a function pointer like so (using the typedef again):

typedef void(*name_of_type)(const time_point<Clock>&)>

And then replace name_of_type with whatever name you want.

This way you can use the operator== with the function pointers


Update #2:

I will clarify it all by putting all into your class:

template<typename Clock, typename Duration>
class Timer
{
public:
    typedef void(*name_of_type)(const time_point<Clock>&)>

    void Register(name_of_type eventHandler);

private:
    std::vector<name_of_type> eventHandlers;
// Some more stuff.
};

With the for loop, you can then do something like:

[non-c++11]

typename vector<name_of_type>::iterator it;
for(it = eventHandlers.begin(); it != eventHandlers.end(); ++it)
{
//do what you want with *it
}

[c++11 onwards]

for(auto& x: eventHandlers)
{
//do what you want with x
}
Joe
  • 380
  • 2
  • 6