I have the following interface:
struct A {};
struct B
{
using Cb = std::function<void(A& a)>;
using ConstCb = std::function<void(const A& a)>;
virtual void visit(ConstCb cb) const = 0;
virtual void visit(Cb cb) = 0;
};
B::visit()
shall enumerate all members of itself that are of type A
.
Now, since B::visit() might become complex in deriving classes, so duplicating the implementation of visit()
is not nice. Meyers advises const-casting (cf. here).
So an approach would be:
struct B
{
using Cb = std::function<void(A& a)>;
using ConstCb = std::function<void(const A& a)>;
void visit(Cb cb);
void visit(ConstCb cb) const;
protected:
virtual void doVisit(ConstCb) const = 0;
};
void B::f(ConstCb cb) const
{
doVisit(cb);
}
void B::f(Cb cb)
{
static_cast<const B*>(this)->f(/* somehow cast cb to ConstCb */);
}
However, exactly that missing piece seems to be impossible. I can get a function pointer of cb
using std::function::target()
and then try to cast it to the other type. But this is impossible, since target()
doesn't work for lambdas, they can't be converted to function pointers (only if they have an empty capture).
So I can't think of a solution right now. Does somebody have any ideas? Perhaps the whole approach is flawed already :D