Archived

This forum has been archived. Please start a new discussion on GitHub.

macro to resolve ambiguous-base Ice::Object methods

If I want to implement two distinct Ice interfaces in one class, I have to manually forward the Ice::Object internal methods to ::Ice::Object, or else suffer g++'s "no unique final overrider" wrath. Rather than duplicate the (considerable) typing every time I hit one of those, or write one-off slice interfaces to have slice2cpp generate the forwarding for me -- at some code size cost as well -- I use the following macro:
#define ICE_FORWARD_ICE_OBJECT_METHODS                                                               \
    virtual bool ice_isA(const std::string& i, const ::Ice::Current& c) const { return ::Ice::Object::ice_isA(i, c); } \
    virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& c = ::Ice::Current()) const { return ::Ice::Object::ice_ids(c); } \
    virtual const ::std::string& ice_id(const ::Ice::Current& c= ::Ice::Current()) const { return ::Ice::Object::ice_id(c); } \
    virtual ::IceInternal::DispatchStatus __dispatch(::IceInternal::Incoming& i, const ::Ice::Current& c) { return ::Ice::Object::__dispatch(i, c); } \
    virtual void __write(::IceInternal::BasicStream* s, bool b) const { ::Ice::Object::__write(s, b); } \
    virtual void __read(::IceInternal::BasicStream* s, bool b = true) { ::Ice::Object::__read(s, b); } \
    virtual void __gcReachable(::IceUtil::GCObjectMultiSet& ms) const { ::Ice::Object::__gcReachable(ms); } \
    virtual void __gcClear() { ::Ice::Object::__gcClear(); }

I think it would look quite spiffy in Ice/Object.h, myself!

Mike

Comments

  • marc
    marc Florida
    Hmm... I'm surprised that this works. For example, you overload ice_isA() to use the version of the base class, so all checked casts to a derived interface fail, don't they? And how are calls dispatched, since you forward __dispatch() to the base class as well?

    In general, I recommend to not to use such code that relies on Ice internals. Such code could break when we make changes to internals.
  • Originally posted by marc
    Hmm... I'm surprised that this works. For example, you overload ice_isA() to use the version of the base class, so all checked casts to a derived interface fail, don't they? And how are calls dispatched, since you forward __dispatch() to the base class as well?
    Honestly, now that you ask, I don't really know. It seems to work, but I agree that it sure shouldn't.

    What I'm trying to achieve is having checkedCast act like QueryInterface, I suppose, but maybe I want facets or some other mechanism for this purpose. Am I "not supposed" to have my servant inherit from multiple disjoint interfaces? I guess I need some more sophisticated dispatching mechanism, based on the incoming identity or something.

    Hrm. How embarrassing.

    Mike