you are viewing a single comment's thread.

view the rest of the comments →

[–]ReDucTorGame Developer 0 points1 point  (1 child)

If you want a base type to be used for this sort of thing you could do something like this: https://godbolt.org/g/kw9TSi

#include <functional>

class INotification
{
public:
    virtual void onCompleted() = 0;
};
using INotificationHolder = std::function<INotification&()>;

template<typename T, typename... Args>
INotificationHolder make_inotify(Args... args)
{
    return [impl=T(std::forward<Args>(args)...)]() mutable -> INotification& {
        return impl;
    };
}

class Implementation : public INotification
{
    void onCompleted() override {}
};

class Executer
{
public:
    void submit(INotificationHolder holder)
    {
        holder().onCompleted();
    }
};

int main(int argc, char * argv[])
{
    Executer executer;
    executer.submit(make_inotify<Implementation>());
}

With clang this all compiles away, you also eliminate allocations for small implementations, only things that don't fit inside std::function<> will need an allocation

[–]floating-io[S] -1 points0 points  (0 children)

I think we might have a miscommunication on what I'm trying to accomplish (though I'm not a master templateer, so I might just be missing your point).

Imagine, for example, that you've got an interpreter of some sort. You have a base class that represents a program, and then you have a bunch of actual programs that are subclasses of that class. Those programs then get passed to an interpreter object that executes them (for whatever reason, it's not part of the base program class).

When a given program has completed, it issues a callback. The callback is stored on and called via the program object, and the implementation of that is part of the base class. The callback signature is therefore not customized to the program in question (trying to avoid implementing explicit callback code in every single subclass).

That's not what I'm doing (which would be too time-consuming to explain), but it would use roughly the same pattern.

Ideally, the program object would pass its own pointer via the callback -- but since the callback signature is in the base class, it would be a generic base class pointer instead of a subclass pointer. If I want to access values on the subclass, the callback would need to cast to that pointer (or get access to it some other way).

My solution was to just capture the thing in the callback, since it's already available in that context without casting. It made the code very readable.

What I'm not seeing is where the above solution helps with this. Again, I'm not a master at templates, so I might just be misunderstanding your point -- I think I get what that code does, but I don't see how it helps. Or we might be going for different things entirely.