LINUX.ORG.RU

История изменений

Исправление quasimoto, (текущая версия) :

Или просто руками расписывать все нужные размещения:

#include <cstdio>

struct IApplyForce {
    virtual void ApplyForce() = 0;
};

struct IRotateObject {
    virtual void RotateObject() = 0;
};

struct ISetFriction {
    virtual void SetFriction() = 0;
};

template <class...>
struct IComb;

template <>
struct IComb<> {};

template <>
struct IComb<IApplyForce, ISetFriction> : public IApplyForce, public ISetFriction {};

template <>
struct IComb<IApplyForce, IRotateObject> : public IApplyForce, public IRotateObject {};

template <>
struct IComb<IApplyForce, ISetFriction, IRotateObject> : public ISetFriction, public IComb<IApplyForce, IRotateObject> {};

/* ... */

struct Engine1: public IComb<IApplyForce, ISetFriction, IRotateObject> {
    virtual void ApplyForce() { puts("Engine1::ApplyForce"); }
    virtual void RotateObject() { puts("Engine1::RotateObject"); }
    virtual void SetFriction() { puts("Engine1::SetFriction"); }
};

struct Engine2: public IComb<IApplyForce, IRotateObject> {
    virtual void ApplyForce() { puts("Engine2::ApplyForce"); }
    virtual void RotateObject() { puts("Engine2::RotateObject"); }
};

struct Engine3: public IComb<IApplyForce, ISetFriction> {
    virtual void ApplyForce() { puts("Engine3::ApplyForce"); }
    virtual void SetFriction() { puts("Engine3::SetFriction"); }
};

int main()
{
    IComb<IApplyForce, IRotateObject> *engine = new Engine1;
    engine->ApplyForce();
    engine->RotateObject();

    engine = new Engine2;
    engine->ApplyForce();
    engine->RotateObject();

    // engine = new Engine3;
}

Исправление quasimoto, :

Или просто руками расписывать все нужные размещения:

#include <cstdio>

/*
 * Interfaces.
 */

struct IApplyForce {
    virtual void ApplyForce() = 0;
};

struct IRotateObject {
    virtual void RotateObject() = 0;
};

struct ISetFriction {
    virtual void SetFriction() = 0;
};

template <class...>
struct IComb;

template <>
struct IComb<> {};

template <>
struct IComb<IApplyForce, ISetFriction> : public IApplyForce, public ISetFriction {};

template <>
struct IComb<IApplyForce, IRotateObject> : public IApplyForce, public IRotateObject {};

template <>
struct IComb<IApplyForce, ISetFriction, IRotateObject> : public ISetFriction, public IComb<IApplyForce, IRotateObject> {};

/* ... */

struct Engine1: public IComb<IApplyForce, ISetFriction, IRotateObject> {
    virtual void ApplyForce() { puts("Engine1::ApplyForce"); }
    virtual void RotateObject() { puts("Engine1::RotateObject"); }
    virtual void SetFriction() { puts("Engine1::SetFriction"); }
};

struct Engine2: public IComb<IApplyForce, IRotateObject> {
    virtual void ApplyForce() { puts("Engine2::ApplyForce"); }
    virtual void RotateObject() { puts("Engine2::RotateObject"); }
};

struct Engine3: public IComb<IApplyForce, ISetFriction> {
    virtual void ApplyForce() { puts("Engine3::ApplyForce"); }
    virtual void SetFriction() { puts("Engine3::SetFriction"); }
};



int main()
{
    IComb<IApplyForce, IRotateObject> *engine = new Engine1;
    engine->ApplyForce();
    engine->RotateObject();

    engine = new Engine2;
    engine->ApplyForce();
    engine->RotateObject();

    // engine = new Engine3;
}



#include <cstdio>

struct IApplyForce {
    virtual void ApplyForce() = 0;
};

struct IRotateObject {
    virtual void RotateObject() = 0;
};

struct ISetFriction {
    virtual void SetFriction() = 0;
};

template <class...>
struct IComb;

template <>
struct IComb<> {};

template <>
struct IComb<IApplyForce, ISetFriction> : public IApplyForce, public ISetFriction {};

template <>
struct IComb<IApplyForce, IRotateObject> : public IApplyForce, public IRotateObject {};

template <>
struct IComb<IApplyForce, IRotateObject, ISetFriction> : public ISetFriction, public IComb<IApplyForce, IRotateObject> {};

struct Engine1: public IComb<IApplyForce, IRotateObject, ISetFriction> {
    virtual void ApplyForce() { puts("Engine1::ApplyForce"); }
    virtual void RotateObject() { puts("Engine1::RotateObject"); }
    virtual void SetFriction() { puts("Engine1::SetFriction"); }
};

struct Engine2: public IComb<IApplyForce, IRotateObject> {
    virtual void ApplyForce() { puts("Engine2::ApplyForce"); }
    virtual void RotateObject() { puts("Engine2::RotateObject"); }
};

struct Engine3: public IComb<IApplyForce, ISetFriction> {
    virtual void ApplyForce() { puts("Engine3::ApplyForce"); }
    virtual void SetFriction() { puts("Engine3::SetFriction"); }
};

int main()
{
    IComb<IApplyForce, IRotateObject> *engine = new Engine1;
    engine->ApplyForce();
    engine->RotateObject();

    engine = new Engine2;
    engine->ApplyForce();
    engine->RotateObject();

    // engine = new Engine3;
}

Исходная версия quasimoto, :

Или просто руками расписывать все нужные размещения:

#include <cstdio>

struct IApplyForce {
    virtual void ApplyForce() = 0;
};

struct IRotateObject {
    virtual void RotateObject() = 0;
};

struct ISetFriction {
    virtual void SetFriction() = 0;
};

template <class...>
struct IComb;

template <>
struct IComb<> {};

template <>
struct IComb<IApplyForce, ISetFriction> : public IApplyForce, public ISetFriction {};

template <>
struct IComb<IApplyForce, IRotateObject> : public IApplyForce, public IRotateObject {};

template <>
struct IComb<IApplyForce, IRotateObject, ISetFriction> : public ISetFriction, public IComb<IApplyForce, IRotateObject> {};

struct Engine1: public IComb<IApplyForce, IRotateObject, ISetFriction> {
    virtual void ApplyForce() { puts("Engine1::ApplyForce"); }
    virtual void RotateObject() { puts("Engine1::RotateObject"); }
    virtual void SetFriction() { puts("Engine1::SetFriction"); }
};

struct Engine2: public IComb<IApplyForce, IRotateObject> {
    virtual void ApplyForce() { puts("Engine2::ApplyForce"); }
    virtual void RotateObject() { puts("Engine2::RotateObject"); }
};

struct Engine3: public IComb<IApplyForce, ISetFriction> {
    virtual void ApplyForce() { puts("Engine3::ApplyForce"); }
    virtual void SetFriction() { puts("Engine3::SetFriction"); }
};

int main()
{
    IComb<IApplyForce, IRotateObject> *engine = new Engine1;
    engine->ApplyForce();
    engine->RotateObject();

    engine = new Engine2;
    engine->ApplyForce();
    engine->RotateObject();

    // engine = new Engine3;
}