Before I ask what I want to know, here's a little background: I'm wrapping a std::function
in my own class Function
, which stores some additional data along with the std::function
object. Later on, I have a std::vector<Function<Signature>>
that stores a whole bunch of Function
's of the same signature (e.g. void(int)
). These std::function
's may represent normal free functions, functors, or member functions that have been bound to an object using std::bind
.
At some later point, I want to traverse the std::vector
, and check some properties of the Function
objects. For example, I want to select every Function
that is bound to a particular member-function (regardless of the object it will be called on). This means I have to find a way to store these member-function pointers, while discarding their exact type. In other words, I need to be able to store a pointer of type void (A::*)()
and another pointer of type void (B::*)()
in the same field.
I used to do this using a union
to 'cast' the member-function-pointer to a void*
, but then found out that member-function-pointers are implementation-defined and don't have the same size as pointers. Now I'm looking for a portable solution, and this is what I came up with:
class MemFunPtr
{
friend bool operator==(MemFunPtr const &lhs, MemFunPtr const &rhs);
enum { SIZE = sizeof(void(MemFunPtr::*)()) };
char buf[SIZE];
public:
template <typename T, typename R, typename ... Args>
MemFunPtr(R (T::*ptr)(Args ...))
{
union
{
R (T::*memfcn_)(Args ...);
char buf_[SIZE];
} caster;
caster.memfcn_ = ptr;
memcpy(buf, caster.buf_, SIZE);
}
};
bool operator==(MemFunPtr const &lhs, MemFunPtr const &rhs)
{
return memcmp(lhs.buf, rhs.buf, MemFunPtr::SIZE) == 0;
}
Now my question is, if this is portable. I would be even more happy with a more straightforward way of doing this. I looked in to std::mem_fn
, but it seems that the type of these objects is unspecified (the examples on cppreference.com use auto
), so I don't think this is where the solution lies.
Aucun commentaire:
Enregistrer un commentaire