0

I am trying to create a queue of callable elements with state so I can store the callable element (with an integer indicating when it should be called) and then call it later (after checking the stored integer within it).

I have been reading about functors and the std::function template for the past few days and I am wondering which one of the following two options would be better in terms of both memory and performance (which is better for each, if different).

1st Option:

class UpdateFunction : public std::function<bool(unsigned long long int)> {
public:    
    unsigned long long int _intendedTime;
};

void main()
{
    typedef std::deque<UpdateFunction> UpdateQueue;
    UpdateQueue _updateQueue;

    _updateQueue.push_back(UpdateFunction([](unsigned long long int time)->bool{return outsideFunction(time);}));
    _updateQueue.back()._intendedTime = 10;
}

2nd Option:

class UpdateFunction {
    bool (*_fn)(unsigned long long int);
    unsigned long long int _intendedTime;

    UpdateFunction::UpdateFunction(bool (*fn)(unsigned long long int), unsigned long long int time)
        : _fn(fn),
          _intendedTime(time)
    {
    }

    bool operator()(unsigned long long int time)
    {
        return _fn(time);
    }
};

void main()
{
    typedef std::deque<UpdateFunction> UpdateQueue;
    UpdateQueue _updateQueue;

    _updateQueue.push_back(UpdateFunction(outsideFunction, 10));
}

I have never seen any code where someone derives from std::function so I'm not even sure this would work as expected.

An answer which comes close to what I'm trying to do is this: https://stackoverflow.com/a/9050114/4076418, but I don't need variable arguments (actually, I have only one single signature, which is in the code above), so I thought it might be better to just derive from std::function instead of contain an instance of it. To be honest, I have no idea how slow or fast std::function is; I've read mentions of type erasure but I'm still trying to figure out what that is.

NB: I am a C++ beginner and I'm trying to wrap my head around references and move semantics, so I apologize if there are obvious errors in the code, or if the coding style is horrible.

Community
  • 1
  • 1
elatalhm
  • 516
  • 3
  • 12

1 Answers1

2

I would go with a variant of option 2. This gives you the flexibility of function but avoids the headache of subclassing and needing to deal with the constructors.

struct UpdateFunction {
    std::function<bool(unsigned long long int)> fn;
    unsigned long long int _intendedTime;
};

You don't even need a special constructor, you can just say

queue.push_back(UpdateFunction{outsideFunction, 10});
StilesCrisis
  • 15,972
  • 4
  • 39
  • 62
  • That's actually an elegant solution. But I'm not sure if it would fit my case due to an error on my part. I (foolishly) omitted that the outsideFunction has more parameters than the callable elements in the queue and that's why I was using a lambda in the 1st option. Sorry, but thank you :) – elatalhm Sep 25 '14 at 00:54
  • I realise how messed up the code I wrote is, and that it wouldn't work for the 2nd option if outsideFunction has more parameters. I'm fixing it right now. – elatalhm Sep 25 '14 at 00:55
  • 1
    Thanks for the answer. After a lot of confusion, I realised that my question is pretty much moot. I was wondering if I could just get away with a function pointer as in my original option 2, but it turns out if I want to use currying and lambda's variable capture, I have to use std::function anyway (as far as I understand). And the absence/presence of std::function was why I was asking about performance. – elatalhm Sep 25 '14 at 01:27
  • A major selling point for `function` here is the ability to mix in extra arguments/reorder. That's totally an expected use case, not unusual at all. – StilesCrisis Sep 25 '14 at 03:29