How to tell a C++ mixin the interface it implements - c++

I have an interface and a class implementing it:
class InterfaceA
{
public:
enum Enum { X, Y, Z };
virtual void foo(Enum &) = 0;
virtual void bar() = 0;
};
class ClassA : public InterfaceA
{
public:
virtual void foo(Enum & a) {
a = X;
}
virtual void bar();
};
I need to extend the functionality of an InterfaceA implementing class in one aspect. In my understanding this is what mixins are for.
E.g. foo() should change its parameter value on some condition. Here is how I do it:
template <typename T>
class Mixin : public T
{
public:
virtual void foo(Enum & a) {
T::foo(a);
if (a == X){
a = Y;
}
}
};
The problem is, it won't compile unless I either write scope prefixes to identifiers defined in the interface class or typedef them like this:
template <typename T>
class Mixin : public T
{
public:
typedef InterfaceA::Enum Enum;
virtual void foo(Enum & a) {
T::foo(a);
if (a == InterfaceA::X){
a = InterfaceA::Y;
}
}
};
It's not a big deal if there are few such types coming from the interface definition. But if there are many, it can become ugly. I would like the code to reflect the fact that a Mixin manipulates an InterfaceA object by design. Unfortunately inheriting Mixin from InterfaceA introduces a 'dreaded diamond' which I'd better avoid. Is that possible?

Enum, X and Y should be dependent typename.
And you may use static_assert to force inheritance.
template <typename T>
class Mixin : public T
{
public:
static_assert(std::is_base_of<InterfaceA, T>::value,
"T should inherit from InterfaceA");
virtual void foo(typename T::Enum & a) {
T::foo(a);
if (a == T::X){
a = T::Y;
}
}
};

I suppose you should use virtual inheritance; this should avoid "dreaded diamond" problem.
Something like
class InterfaceA
{
public:
enum Enum { X, Y, Z };
virtual void foo(Enum &) = 0;
virtual void bar() = 0;
};
class ClassA : public virtual InterfaceA
{
public:
virtual void foo(Enum & a) {
a = X;
}
virtual void bar() {
}
};
template <typename T>
class Mixin : public T, public virtual InterfaceA
{
public:
virtual void foo(Enum & a) {
T::foo(a);
if (a == X){
a = Y;
}
}
};
int main ()
{
Mixin<ClassA> m;
return 0;
}

Related

Is it possible to override functionality with a mixin-like pattern in c++

let's say I have the following classes:
class Base {
public:
virtual int do_something() = 0;
protected:
virtual int give_intermediate_result(int) = 0;
int m_some_shared_resources;
};
class Foo : public Base {
public:
virtual int do_something() override { return give_intermediate_result(1); }
protected:
virtual int give_intermediate_result(int a) override { return a*2; }
};
// and something like this:
class FooMixinA : public virtual Base {
protected:
virtual int give_intermediate_result(int) override;
};
class FooMixinB : public virtual Base {
public:
virtual int do_something() override;
};
What I would like to do is something like this:
Foo<FooMixinA, FooMixinB> myfoo (...);
which basically should override Foo's implementation of do_something with that of FooMixinB and give_intermediate_result with that of FooMixinA. Additionally I want mixins to be able to replace other mixins functionality, i. e. the order of the mixins is important as one mixin may use (f. e. the get_intermediate_result of) another mixin.
At the same time they should all have access to some shared underlying resource.
Can I do something like that and if so how would I approach it?
template<class Base, template<class>class...Mixins>
struct Foo:Base{};
template<class Base, template<class>class M0, template<class>class...Mixins>
struct Foo<Base, M0, Mixins...>:M0<Foo<Base, Mixins...>>{};
struct Base{
virtual int A()=0;
virtual int B()=0;
virtual ~Base()=default;
};
template<class Base>
struct MixinA:Base{
int A() final{ return 3; }
};
template<class Base>
struct MixinB:Base{
int B() override{ return -1; }
};
template<class Base>
struct MixinB2:Base{
int B() final{ return 0; }
};
using Bob=Foo<Base, MixinA, MixinB2, MixinB>;
std::unique_ptr<Base> pBase=std::make_unique<Bob>();
std::cout << pBase->A() << pBase->B() <<'\n';
Leftmost mixins override rightmost ones here.
For the other way around
template<class Base, template<class>class M0, template<class>class...Mixins>
struct Foo<Base, M0, Mixins...>:Foo<M0<Base>, Mixins...>{};
We can remove the Base argument of Foo if you really want. For right-to-left application:
template<template<class>class...Mixins>
struct Foo:Base{};
template<template<class>class M0, template<class>class...Mixins>
struct Foo<M0, Mixins...>:M0<Foo<Mixins...>>{};
it is easy. For left-to-right, you need to get fancier.

Diamond inheritance - call all parent functions

Say I've got the following (pseudo-)code:
class base{
public:
virtual void callMe() = 0;
virtual void doRender() = 0;
}
class a : public base{
public:
virtual void callMe(){/*doA*/} override;
}
class b : public base{
public:
virtual void callMe(){/*doB*/} override;
}
class myClass : public base, public a, public b{
public:
virtual void doRender(){
this->a::callMe();
this->b::callMe();
} override;
}
Would there be a way to write this differently? Something like:
class myClass : public base, public a, public b{
public:
virtual void doRender(){
this->allSupers::callMe();
} override;
}
My goal with this would be to have a base class that can be extended to have different "features", all of which have to be executed on doRender.
I know I could of course keep track of these functions by means of a function pointer list in base, in which the subclasses put their own functions when constructed, but I'd like to avoid that. Having to iterate over these functions still gives me at least three lines of code in my final doRender. (Or one long unreadable line.)
I'm open for suggestions using templates.
Depending on you actual problem at hand, you might be able to use the mixin-style. Essentially you can have each class call the next callMe at the end (or begining) of their own callMe. One benefit is that callMe does not need to be a virtual function. Here is a minimal example (online):
#include <iostream>
class base
{
public:
void callMe() {}; // Empty base case
virtual void doRender() = 0;
};
template <class super>
class a : public super
{
public:
void callMe()
{
std::cout << "doA" << '\n';
super::callMe(); // Call the next
};
};
template <class super>
class b : public super
{
public:
void callMe()
{
std::cout << "doB" << '\n';
super::callMe(); // Call the next
};
};
template <class super>
class myClass_t : public super
{
public:
void doRender()
{
super::callMe();
};
};
using myClass = myClass_t<a<b<base> > >; // Defining the order of evaluation;
int main()
{
myClass m;
m.doRender();
}
With variadic template, you may do:
template <typename ... Ts>
class myClassTs : public base, public Ts...
{
public:
virtual void doRender(){
int dummy[] = {0, (Ts::callMe(), void(), 0)...};
static_cast<void>(dummy); // Silent warning for unused variable
} override;
}
using myClass = myClassTs<a, b>;
And in C++17, it would be
template <typename ... Ts>
class myClassTs : public base, public Ts...
{
public:
virtual void doRender(){
(static_cast<void>(Ts::callMe()), ...);
} override;
}

multiple inheritance for function only - without virtual and CRTP

How to do multiple inheritance just for function?
must share data of the base class
no virtual function (assume that vtable is expensive)
avoid virtual inheritance
implementation must be able to reside in .cpp
c++14 is allowed
Here are similar questions :-
Multiple inheritance in diamond shape with functions only - use virtual inheritance. Virtual inheritance is generally bad and expensive.
multiple inheritance without virtual inheritance - focuses on syntax and compiling rather than programming technique.
Multilevel inheritance in c++ (CRTP) , CRTP and multilevel inheritance , Eliminate redundancy with CRTP and multiple inheritance (C++03) and Using CRTP with virtual inheritance - implementation must be in header
Here is a sample code (coliru demo) :-
class O{
protected: int database=0;
};
class A : public O{
public: void print(){
std::cout<<database<<std::endl;
}
};
class B : public O{
public: void set(int s){
database=s+1;
}
};
class AB : public O{
public: void print(){//duplicate
std::cout<<database<<std::endl;
}
public: void set(int s){//duplicate
database=s+1;
}
};
//AB ab; ab.set(1); ab.print(); // would print 2
Here is my attempt (wandbox demo). I abuse CRTP :( :-
class O{
public: int database=0;
};
template<class T>class OA{
public: void print(){
std::cout<<static_cast<T*>(this)->database<<std::endl;
}
};
template<class T>class OB{
public: void set(int s){
static_cast<T*>(this)->database=s+1;
}
};
class A :public O,public OA<A>{};
class B :public O,public OB<B>{};
class AB :public O,public OA<AB>,public OB<AB>{};
It works, but it looks inelegant.
Furthermore, implementation must be in header (because OA and OB are template classes).
Are there better approaches? Or is this the way to go?
Sorry if it is too newbie question or already asked. I am a C++ beginner.
Edit
Give extended example of using please.
In ECS, it would be useful in some cases :-
class O{
protected: EntityHandle e;
};
class ViewAsPhysic : public O{ //A
public: void setTransform(Transformation t){
Ptr<PhysicTransformComponent> g=e;
g->transform=t;
}
};
class ViewAsLight : public O{ //B
public: void setBrightness(int t){
Ptr<LightComponent> g=e;
g->clan=t;
}
};
class ViewAsLightBlock : public O{ //AB
//both functions
};
The problem here is that the database field is member of class O. So without virtual inheritance, A and B will have each their own copy of database. So you must find a way to force A and B to share same value. You could for example use a reference field initialized in a protected constructor:
#include <iostream>
class O{
int _db;
protected: int &database;
O(): database(_db) {};
O(int &db): database(db) {};
};
class A : public O{
public: void print(){
std::cout<<database<<std::endl;
}
A() {} // public default ctor
protected: A(int& db): O(db) {}; // protectect ctor
};
class B : public O{
public: void set(int s){
database=s+1;
}
B() {} // public default ctor
protected: B(int& db): O(db) {}; // protectect ctor
};
class AB : public A, public B {
int _db2;
public: AB(): A(_db2), B(_db2) {}; // initialize both references to same private var
};
int main() {
AB ab;
ab.set(1);
ab.print();
return 0;
}
displays as expected:
2
Above code uses no virtual inheritance, no virtual function and no templates, so method can safely implemented in cpp files. The class AB actually uses methods from its both parents and has still a coherent view on its underlying data. In fact it simulates an explicit virtual inheritance by building the common data in the most derived class and injecting in through protected constructors in its parents.
Something like this?
must share data of the base class - check
no virtual function (assume that vtable is expensive) - check
avoid virtual inheritance - check
implementation must be able to reside in .cpp- check
c++14 is allowed - check. c++11 used.
#include <iostream>
class O {
protected:
int database = 0;
};
/*
* the concept of implementing print for a base class
*/
template<class...Bases>
struct implements_print : Bases... {
void print() const {
std::cout << this->database << std::endl;
}
};
/*
* The concept of implementing set for a base class
*/
template<class...Bases>
struct implements_set : Bases... {
void set() {
++this->database;
}
};
struct B : implements_set<O> {
};
struct A : implements_print<O> {
};
struct AB : implements_set<implements_print<O>> {
};
int main() {
A a;
a.print();
B b;
b.set();
AB ab;
ab.set();
ab.print();
}
Another way, using composition and an access class to provide access to the protected member. This example shows how to defer the work on database to another compilation unit:
#include <iostream>
/*
* this stuff in cpp
*/
namespace implementation
{
void print(const int& database) {
std::cout << database << std::endl;
}
void set(int& database) {
++database;
}
}
/*
* this stuff in header
*/
struct OAccess;
class O {
private:
int database = 0;
friend OAccess;
};
struct OAccess {
template<class Host>
constexpr decltype(auto) database(Host &host) const { return (host.database); } // note: () makes reference
template<class Host>
constexpr decltype(auto) database(Host const &host) const { return (host.database); } // note: () makes reference
};
/*
* the concept of implementing print for a derived class
*/
template<class Host>
struct implements_print {
void print() const {
OAccess access;
implementation::print(access.database(self()));
}
private:
decltype(auto) self() const { return static_cast<Host const &>(*this); }
};
/*
* The concept of implementing set for a derived class
*/
template<class Host>
struct implements_set {
void set() {
OAccess access;
implementation::set(access.database(self()));
}
private:
decltype(auto) self() { return static_cast<Host &>(*this); }
};
template<template<class> class...Impls>
struct OImpl : Impls<OImpl<Impls...>> ..., O {
};
using B = OImpl<implements_set>;
using A = OImpl<implements_print>;
using AB = OImpl<implements_print, implements_set>;
int main() {
A a;
a.print();
B b;
b.set();
AB ab;
ab.set();
ab.print();
}
We start with defining the concepts of things that can print and things that can be set:
namespace util {
template<class Base, class Derived, class R=void>
using if_base = std::enable_if_t< std::is_base_of< std::decay_t<Base>, std::decay_t<Derived>>::value, R >;
struct stub {};
}
namespace concepts {
template<class Token>
void do_print(Token, util::stub const&)=delete;
template<class Token>
void do_set(Token, util::stub&, int)=delete;
struct has_print {
struct token { friend struct has_print; private: token(int){} };
template<class T>
friend util::if_base<has_print, T> print(T const& t) {
do_print(get_token(), t);
}
private: static token get_token() { return 0; }
};
struct has_set {
struct token { friend struct has_set; private: token(int){} };
template<class T>
friend util::if_base<has_set, T> set(T& t, int x) {
do_set(get_token(),t, x);
}
private: static token get_token() { return 0; }
};
}
We then declare O and the operations you can support on it:
namespace DB {
class O;
void do_print(::concepts::has_print::token, O const& o);
void do_set(::concepts::has_set::token, O& o, int);
class O{
protected: int database=0;
friend void do_print(::concepts::has_print::token, O const&);
friend void do_set(::concepts::has_set::token, O&, int);
};
class A : public O, public concepts::has_print {
};
class B : public O, public concepts::has_set {
};
class AB : public O, public concepts::has_print, concepts::has_set {
};
}
void DB::do_print(::concepts::has_print::token, O const& o ) { std::cout << o.database << std::endl; }
void DB::do_set(::concepts::has_set::token, O& o, int x) { o.database = x+1; }
The hard part of this is the access control.
I ensure it isn't possible to call do_set except through has_set::set.
That is what all those tokens are about. You can strip them out and their overhead if you are willing to just say "don't call the do_ functions" (and maybe give them another name, like private_impl_set).
Live example.
To start discussion.
class O
{
// no virtual destructor. So cant use polymorphic deletion
// like :
// O *o = new AB;
// delete o;
protected: int database=0;
};
class A : virtual public O{
public: void print(){
std::cout<<database<<std::endl;
}
};
class B : virtual public O{
public: void set(int s){
database=s+1;
}
};
class AB : protected A, protected B{}; // no vtable
void foo() {
AB ab;
ab.print(); // won't perform virtual call.
}

Acyclic Visitor C++

I'm reading the book by Alexandrescu, and I've run into the Acyclic Visitor pattern. I think that it's possible to get rid of the macross that calls AcceptImpl method of the BaseVisitable class.
Could you tell me, whether the following implementation bellow conforms the standard?
class BaseVisitor
{
public:
virtual ~BaseVisitor() {}
};
template <class SpecificVisitable>
class SpecificVisitor
{
public:
virtual void Visit(SpecificVisitable& t) = 0;
protected:
~SpecificVisitor() {}
};
template <class SpecificVisitable>
class BaseVisitable
{
public:
void Accept(BaseVisitor& visitor)
{
SpecificVisitor<SpecificVisitable>& specificVisitor = dynamic_cast<SpecificVisitor<SpecificVisitable>&>(visitor);
specificVisitor.Visit(static_cast<SpecificVisitable&>(*this));
}
protected:
~BaseVisitable() {}
};
class A : public BaseVisitable<A>
{
public:
void PrintA() { std::cout << "A\n"; }
};
class B : public BaseVisitable<B>
{
public:
void PrintB() { std::cout << "B\n"; }
};
class PrintVisitor final:
public BaseVisitor,
public SpecificVisitor<A>,
public SpecificVisitor<B>
{
public:
virtual void Visit(A& a) override
{
a.PrintA();
}
virtual void Visit(B& b) override
{
b.PrintB();
}
};
int main()
{
A a;
B b;
PrintVisitor visitor;
a.Accept(visitor);
b.Accept(visitor);
}
I agree with the commenters to the original post that state that a dynamic_cast to a reference will fail. You are not testing that situation, so your code will of course work just fine. But, in the general case, it's wrong.
I recommend that you instead rewrite BaseVisitable to instead cast to a pointer and check that pointer before dispatching on it. Something like
if (auto sv = dynamic_cast<SpecificVisitor<SpecificVisitable>*>(visitor))
sv->visit(*this)

Override virtual function through CRTP base class

Old: How can I override a virtual function through a CRTP base class?
struct I { virtual void foo() = 0; };
template<class D>
struct B { void foo() { } }; // provides implementation of foo in D
struct D : I, B<D> { }; // D has an implementation of foo that should override I
int main() { D d; }
Error: unimplemented pure virtual method 'foo' in 'D'
Simpler: How can I override a virtual function without reimplementing it in a derived type? (I guess this question goes against the definition of a virtual function).
struct I { virtual void foo() = 0; };
struct B { void foo() { } };
struct D : B, I { };
int main() { D d; }
Besides the obvious but clunky void foo() { B::foo(); } solution, you could separate the "implements a foo" interface from the more complete interface I:
struct FooInterface {
virtual ~FooInterface() {}
virtual void foo() = 0;
};
struct I : public virtual FooInterface {};
template<class D>
struct B : public virtual FooInterface { void foo() { } };
struct D : I, B<D> {};
int main() { D d; }
You can implement D::foo() as a trivial wrapper calling B<D>::foo(). If you have a lot of places that would need to do this, you could make a macro to help out, like:
#define WRAP(CLASS, METHOD) \
METHOD() { return CLASS::METHOD(); }
struct D : I, B<D>
{
void WRAP(B<D>, foo);
};
you're needlessly mixing two different concepts: crtp, and inheriting an implementation of a virtual function
crtp is used for compile time polyrmorphism, virtual functions for runtime polymorphism
that said, you can inherit in an implementation of a virtual function by way of dominance in a virtual inheritance hierarchy, which yields roughly the effect of java/c# implementation inheritance
example:
struct tutti_i
{
virtual int frutti() const = 0;
};
struct tutti_impl_1
: virtual tutti_i
{
int frutti() const override { return 42; }
};
struct base
: virtual tutti_i
{};
struct derived
: base
, tutti_impl_1
{};
#include <iostream>
int main()
{
tutti_i&& tutti = derived();
std::cout << tutti.frutti() << std::endl;
}
For those who don't care whether or not B inherits from I, you can also implement this with CRTP as originally asked:
struct I { virtual void foo() = 0; };
template <class D>
struct B : I { void foo(){ /* Do something fancy with D's type */ } };
struct D : B<D> { };
And if you need further inheritance so that the implementation of foo is always of the most-derived type, you can introduce an intermediate type to disambiguate which implementation of foo gets used:
struct I { virtual void foo() = 0; };
template <class T>
struct B : virtual I { void foo() { /* Do something fancy with the most-derived type */ }};
struct D : B<D> { };
template <typename Base, typename Derived>
struct InheritFrom : public Base, public B<D> { void foo() { B<D>::foo(); } };
struct FurtherDerived : InheritFrom<D, FurtherDerived> { };