+5  A: 

Consider using tested solutions first - Boost.TypeTraits to the rescue:

template<class T>
void takeFooAndBar(const T& t) {
    BOOST_STATIC_ASSERT(
           boost::is_base_of<IFoo, T>::value 
        && boost::is_base_of<IBar, T>::value);
    /* ... */
}
Georg Fritzsche
There is a world outside of boost :-)
rstevens
Of course, bcp helps with that ;) But seriously, why duplicate such a comprehensive collection of compiler-workarounds, especially for type traits and similar?
Georg Fritzsche
I don't think it is a good idea to get out the big boost gun if normal C++ (virtual inheritance) can solve the problem.
rstevens
I don't think of type traits etc. as a big gun, they are good utilities for common busines. In my opinion they also communicate the intent more clearly here.
Georg Fritzsche
+1  A: 

You can achieve the effect using template metaprogramming:

tempate<class C>
void doTest( C* pObj )
{
  pObj->bar();
  pObj->baz();
}

will behave correctly for classes that supply bar() and baz(), and fail to compile for any other classes.

moonshadow
That's very interesting. My real-life case is more complex, actually - I have a class which receives the object that needs to implement both interfaces, keeps a pointer to it, and then calls its methods. I'm not comfortable implementing that big class as a template :(
ggambett
It is possible to code a compile-time assertion that a type provides a particular member function without invoking that function. You could do so in a templated wrapper that then invokes the real function, the templated code being declared with the inline attribute so it compiles away. However, the implementation is hairy - it is easier to use the one from boost (see gf's answer) than roll your own.
moonshadow
+3  A: 

To do this in OO style, you need virtual inheritance to ensure that Fred only ends up with one copy of IBar:

class IFooAndBar : public IFoo, public virtual IBar {};
class IBarAndQuux : public virtual IBar, public IQuux {};

class Fred : public IFooAndBar, public IBarAndQuux {};

Fred fred;
fred.bar(); // unambiguous due to virtual inheritence

As others have said, you can do something similar to your second attempt using templates to get static polymorphism.

The cast you were trying isn't possible, as an instance of Fred isn't an instance of IBarAndBaz. The forced cast compiles because most forced casts will compile, whether or not the conversion is safe, but in this case it will give undefined behaviour.

Edit: Alternatively, if you don't want to use templates and don't like the combinatorical explosion of defining all the possible groups of interfaces, you could define the functions to take each interface as a separate parameter:

void doTest(IBar *bar, IBaz *baz)
{
    bar->bar();
    baz->baz();
}

class Fred : public IBar, public IBaz {};

Fred fred;
doTest(&fred,&fred);
Mike Seymour
That could work. It's unfortunately that I'd have to declare all possible combinations of interfaces (at least the ones I use) in Fred's definition... it would be much better if it could be resolved at the user method location, not at the parameter location, like the template-based solutions do.
ggambett
A: 

What you can do is create a class with a templated constructor that accepts an arbitrary pointer, uses implicit downcasting to get the two interfaces you want, and then implements the combined interface.

struct IFoo 
{
    virtual void foo() = 0;
};

struct IBar 
{
    virtual void bar() = 0;
};

struct IFooAndBar : public IFoo, public IBar {};

class FooAndBarCompositor : public IFooAndBar
{
public:
    template <class T>
    FooAndBarCompositor(T* pImpl) : m_pFoo(pImpl), m_pBar(pImpl) {}

    void foo() {m_pFoo->foo();}
    void bar() {m_pBar->bar();}

private:
    IFoo* m_pFoo;
    IBar* m_pBar;
};

Then you write a function that accepts IFooAndBar* if both interfaces are required, and the caller can construct a FooAndBarCompositor on the stack that dispatches to the object of their choice. It looks like:

void testFooAndBar(IFooAndBar* pI) {}

void baz(Fred* pFred)
{
    FooAndBarCompositor fb(pFred);
    testFooAndBar(&fb);
}

This is not very general, and forces you to write dispatch functions in the compositor. Another approach is to have a generic interface compositor template:

template <class IA, class IB>
class InterfaceCompositor
{
public:
    template <class T>
    InterfaceCompositor(T* pObj) : m_pIA(pObj), m_pIB(pObj) {}

    IA* AsA() const {return m_pIA;}
    operator IA* () const {return AsA();}
    IB* AsB() cosnt {return m_pIB;}
    operator IB* () const {return AsB();}

private:
    IA* m_pIA;
    IB* m_pIB;
};

Then the function looks like:

void testFooAndBar(InterfaceCompositor<IFoo, IBar> pI)
{
    IFoo* pFoo = pI; // Or pI.AsA();
    IBar* pBar = pI; // Of pI.AsB();
}

This requires the function that wants to enforce the multiple interfaces to either use the compositor where an A* or B* is expected (e.g. assignment or function parameter) or explicitly call the appropriate AsX() method. Specifically, the interface to use cannot be inferred from the use of the -> operator and the * operator has no meaning on the composite.

If you go with the generic code, you can use the same template for enforcing that the object support both IBar and IBaz as well.

C++0x will introduce variadic templates that will allow this concept to be extended to arbitrary numbers of interface classes.

ReWrite