No problem...
1) The tacky way, (which is guaranteed to work).
/* mpi++.h */
#define MPI_Comm __C_MPI_Comm
...
#include "mpi.h"
#undef MPI_Comm
...
class MPI_Comm
{
__C_MPI_Comm the_comm;
public:
int Send(void* buf, int count, MPI_Datatype &datatype,
int dest, int tag)
{
return MPI_Send(buf, count, datatype.get_C_handle(),
dest, tag, the_comm);
}
... etc ...
}
2) The clean way.
(Assuming that your C++ compiler has namespace and that
the way I read the standard is what is intended. None of the
three C++ compilers I have will eat this, though YMMV).
/* mpi++.h */
namespace __MPI_impl
{
#include "mpi.h"
}
class MPI_Comm
{
__MPI_impl::MPI_Comm the_comm;
public:
int Send(void* buf, int count, MPI_Datatype &datatype,
int dest, int tag)
{
return __MPI_impl::MPI_Send(buf, count, datatype.get_C_handle(),
dest, tag, the_comm);
}
... etc ...
}
In both these cases you'll actually very likely get away with just passing
(*this) to the underlying C MPI routine where it wants the relevant handle.
In neither case do we rely on knowing the type of the underlying MPI
handle.
> Moreover, for reasons of "design for inheritance" I think it is
> desirable to have the member functions of the C++ objects to be
> virtual. This would break the equivalence between the C struct and
> the C++ object at any rate.
What's the objective in making these virtual ?
When will it ever make sense for a derived class re-implement these
functions and have that affect the base class ? (Which is what virtual is
for.)
You can always override these functions in the derived class if you want
them to be different there, but it seems to me that making these virtual
can only lead to disaster.
(Do I want the derived class's collective ops which are provided by the
base MPI_Comm class to use the derived class's send and recv ? It seems
unlikely and confusing given that we don't say how the collective
operations are implemented.)
Actually, of course, an implementation like either of those above will work
whether or not the class has virtual functions. My objection to them is
that I can't see the benefit, and there's a cost on every call.
You can always insert one more class if you *really* need the functions
virtual, of course.
class vmpi_comm : private MPI_Comm {
public:
virtual int Send(...) { return MPI_Comm::Send(...); }
};
Now derive all your classes from vmpi_comm.
-- Jim
James Cownie
BBN UK Ltd
Phone : +44 117 9071438
E-Mail: jcownie@bbn.com