I'm trying to design a policy-based class, where a certain interface is implemented by the policy itself, so the class derives from the policy, which itself is a template (I got this kind of thinking from Alexandrescu's book):
#include <iostream>
#include <vector>
class TestInterface {
public:
virtual void test() = 0;
};
class TestImpl1 {
public:
void test() {std::cerr << "Impl1" << std::endl;}
};
template<class TestPolicy>
class Foo : public TestInterface, TestPolicy {
};
Then, in the main() function, I call test() on (potentially) various different objects that all implement the same interface:
int main() {
std::vector<TestInterface*> foos;
foos.push_back(new Foo<TestImpl1>());
foos[0]->test();
delete foos[0];
return 0;
}
It doesn't compile, though, because
the following virtual functions are pure within ‘Foo<TestImpl1>’:
virtual void TestInterface::test()
I thought TestInterface::test() is implemented because we derive from TestImpl1?
For this to work the policy class needs to inherit from the interface class:
class TestInterface {
public:
virtual void test() = 0;
};
template< class Interface >
class TestImpl1 : public Interface {
public:
void test() {std::cerr << "Impl1" << std::endl;}
};
template<class TestPolicy>
class Foo : public TestPolicy<TestInterface> {
// ...
};
You could also try a boost::mpl approach:
keeping your TestInterface and TestImpl as they are:
#include <boost/mpl/inherit.hpp>
using namespace boost::mpl;
template <class TestPolicy>
class Foo: public inherit2< TestPolicy, inherit2< TestInterface , empty_base >::type >::type
{
...
}
should work
Related
I see this question has been discussed in various places, e.g. here,here,here and here .But, i have still not been able to relate to the questions aforementioned.
My situation:
I am trying to implement a simple generic visitor pattern in C++. The hosts in this pattern are different pets, these are in a file called Pet.h. The visitors are in a separate header called Visitors.h.
The concrete Pet classes accept, generic visitor classes(See Comment 0 in Pet.h), and the generic visitor classes visits the generic Pet classes. So, there is a natural cyclic dependency.
Earlier, when all the code was in a single header, there were no problems. Now there is. To illustrate, here is the Pet.h class.
P.S: I am using Visual Studio 2017.
#pragma once
#include <string>
#include "Visitors.h"
namespace pet
{
class Pet {
public:
virtual ~Pet() {}
virtual void accept(temp_visitor::PetVisitor& v) = 0; //Comment 0 Pet accepts a gneric PetVisitor
virtual std::string getAnimal() = 0;
private:
std::string color_;
};
template <typename Derived>
class Visitable : public Pet {
public:
using Pet::Pet;
Visitable() = default;
Visitable(const std::string& animal) : animal_(animal) {}
void accept(temp_visitor::PetVisitor& v) override {
v.visit(static_cast<Derived*>(this));
}
std::string getAnimal() override
{
return animal_;
}
std::string animal_;
};
class Cat : public Visitable<Cat> {
using Visitable<Cat>::Visitable;
};
class Dog : public Visitable<Dog> {
using Visitable<Dog>::Visitable;
};
}
And here is the Visitors.h file. The void visit(pet::Pet* p) gives the following error "use of undefined type pet::Pet on using p->getAnimal()
#include<iostream>
#pragma once
namespace pet
{
class Pet; //Comment 1. Attempted forward declaration.
}
namespace temp_visitor
{
template <typename ... Types>
class Visitor;
template <typename T>
class Visitor<T> {
public:
virtual void visit(T* t) = 0;
};
using PetVisitor = Visitor<pet::Pet>;
class FeedingVisitor : public PetVisitor {
public:
void visit(pet::Pet* p) override { std::cout << "Feed veggies to the "+ p->getAnimal() << std::endl; } //Comment 2: Gives the following error "use of undefined type pet::Pet"
};
}
So how do i fix this problem ?
You need to move the FeedingVisitor to a new header and cpp as well. In header you will have #include "Visitors.h", forward declration for Pet and in cpp #include "Pet.h"
Something like
Visitors.hpp
namespace pet {
class Pet; //Comment 1. Attempted forward declaration.
}
namespace temp_visitor
{
template <typename ... Types> class Visitor;
template <typename T> class Visitor<T>
{
public:
virtual void visit(T* t) = 0;
};
}
FeedingVisitor.hpp
#include "Visitors.h"
namespace temp_visitor
{
using PetVisitor = Visitor<pet::Pet>;
class FeedingVisitor : public PetVisitor {
public:
void visit(pet::Pet* p) override; // only declaration
};
}
FeedingVisitor.cpp
// move the definition to cpp
void temp_visitor::FeedingVisitor::visit(pet::Pet* p) {
std::cout << "Feed veggies to the " + p->getAnimal() << std::endl;
}
Well, i have next code:
#include <type_traits>
#include <iostream>
#include <string>
#include <list>
#include <functional>
class base_main
{
public:
virtual ~base_main()
{
}
// some methods
};
class base_1 : virtual public base_main
{
// some methods
};
class base_2 : virtual public base_main
{
// some methods
};
class base_3 : virtual public base_main
{
// some methods
};
class object : public base_1, public base_2, public base_3
{
// some methods
};
// in other *hpp file
class object_controller_listener
{
public:
virtual void object_created( base_main* o )
{
// well, i want to work only with base_1 and base_2 interfaces, but not with base_3, and also i don't want to know something about object class in this *hpp
// is it good code design?
auto* xxx = dynamic_cast<base_1*>( o );
}
};
class objects_controller
{
void create()
{
std::unique_ptr<object> obj;
// ...
for( auto listener : m_listeners )
listener->object_created( obj.get() );
}
std::list<object_controller_listener*> m_listeners;
};
int main()
{
}
The question is - how can i work only with base_1 and base_2 interfaces? Should i create two separate listeners for them, and send two events in create() function, or should i use dynamic_cast for downcasting and send only one event in create() function? Is this good code design or is this feels like code smell?
UPD:
For example: base_1 - is render_base class, which contains render data, and have functions for set and get this data base_2 - collider base class which contains collider data, and have functions for set and get this data base_3 is physic base class and object is inheritance of all this classes. And when i want work only with render class i use create event which send only render_base class to the render_system, which works only with renders objects and truly use polymorphism. But if i want in some other place work with collider and physic objects, without knowledge about render - how can i use polymorphism here in base classes?
It is hard to tell what design you should choose as this heavily depends on the overall structure of the application.
Generally, I would avoid having a function with the signature virtual void object_created( base_main* o ) in which you dynamically cast to base_* and work on that directly in this function. Because the function signature is part of the documentation of the API.
So I would create distinct functions for base_1 and base_2 and call those.
How to do that depends again on the overall structure. You could create a helper function, that forwards the call to the other functions (this is just a fast implementation how that could look like:
template <typename DestT, typename SrcT, typename T>
void forward_if(SrcT obj, T *o, void (T::*f)(DestT)) noexcept {
if (auto tmp = dynamic_cast<DestT>(obj); tmp != nullptr) {
(o->*f)(tmp);
}
}
And then you could use it like this:
#include <iostream>
#include <vector>
class base_main {
public:
virtual ~base_main() {}
};
class base_1 : virtual public base_main {};
class base_2 : virtual public base_main {};
class base_3 : virtual public base_main {};
class object : public base_1, public base_2, public base_3 {};
template <typename DestT, typename SrcT, typename T>
void forward_if(SrcT obj, T *o, void (T::*f)(DestT)) noexcept {
if (auto tmp = dynamic_cast<DestT>(obj); tmp != nullptr) {
(o->*f)(tmp);
}
}
struct listener_base {
virtual void object_created(base_main *o) = 0;
};
struct specific_listener : public listener_base {
void object_created(base_main *o) override {
forward_if<base_1 *>(o, this, &specific_listener::object_created);
forward_if<base_2 *>(o, this, &specific_listener::object_created);
}
void object_created(base_1 *o) {
std::cout << "object created base_1" << std::endl;
}
void object_created(base_2 *o) {
std::cout << "object created base_2" << std::endl;
}
};
int main() {
std::vector<listener_base *> listeners;
listeners.push_back(new specific_listener());
object o;
for (auto listener : listeners) {
listener->object_created(&o);
}
return 0;
}
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;
}
For this particular project, I am not able to use C++11 features (e.g. decltype) because the compiler does not yet support them. I need to be able to provide the current class as a template parameter, preferably within a macro without an argument (see below), without dressing up the class declaration or hiding curly braces, etc.
class Foo: private Bar<Foo> {
MAGIC //expands to using Bar<Foo>::Baz; and some others
public:
void otherFunction();
//... the rest of the class
};
Ideally, I'd like this to work very much like Qt's Q_OBJECT macro, but without introducing another pre-compile step and associated generated classes. typeid might be useful at runtime, but my goal is to accomplish all of this at build.
How do I write the MAGIC macro so that I don't need to repeat the class name each time?
What about:
template<typename T>
class Base
{
protected:
typedef Base<T> MagicBaseType;
namespace Baz { }
};
class Derived1 : private Base<Derived1>
{
using MagicBaseType::Baz;
}
class Derived1 : private Base<Derived2>
{
using MagicBaseType::Baz;
}
or, if you can't modify the Base definition, using templates and multiple inheritance
template<typename T>
class Base
{
protected:
namespace Baz { }
};
template<typename T>
class DerivedTemplate : public T
{
protected:
typedef typename T BaseType;
}
class Derived : public Base<Derived>, public DerivedTemplate<Base<Derived>>
{
using BaseType::Baz;
}
I don't think there is any language supported mechanism to extract the base type from a class. You can use:
Option 1
class Foo: private Bar<Foo> {
#define BASE_TYPE Bar<Foo>
// Use BASE_TYPE in MAGIC
MAGIC //expands to using Bar<Foo>::Baz; and some others
#undef BASE_TYPE
public:
void otherFunction();
//... the rest of the class
};
Option 2
class Foo: private Bar<Foo> {
typedef Bar<Foo> BASE_TYPE;
// Use BASE_TYPE in MAGIC
MAGIC //expands to using Bar<Foo>::Baz; and some others
public:
void otherFunction();
//... the rest of the class
};
If you really don't care about formatting or writing a maintenance headache you can do this without repeating the type by having the macro take the type argument:
#define MAGIC(BASE) \
BASE { \
using BASE::baz;
class Sub : private MAGIC(Base<Foo>)
public:
void otherFunction();
};
but this makes me feel pretty bad about myself
You could use a "proxy"(?) struct for Building up the inheritance:
template <typename S>
struct Base : public S{ //always public, access is restricted by inheriting Base properly
using super = S;
};
Usage would be as follows:
#include <iostream>
template <typename S>
struct Base : public S {
using super = S;
};
template <typename T>
class Bar
{
public:
virtual void f() { std::cout << "Bar" << std::endl; }
};
class Foo : private Base<Bar<int>>
{
public:
virtual void f()
{
std::cout << "Foo";
super::f(); //Calls Bar<int>::f()
}
};
class Fii : private Base<Foo>
{
public:
virtual void f()
{
std::cout << "Fii";
super::f(); //Calls Foo::f()
}
};
int main()
{
Fii fii;
fii.f(); //Print "FiiFooBar"
return 0;
}
Playing a bit with variadic templates to try and see what could be done with them, I found myself wondering about something:
Let's suppose I have a class which can take several other classes as template parameters, each of them have a nested class (let's call it nested_class):
template<typename... Classes> class MyClass {
class InnerClass { ... };
};
what I would like to achieve is inside MyClass, create a class that inherits from each of the parameters classes nested class.
For example:
class A1 {
public:
struct nested_class {
do_stuff() { ... }
};
};
class A2 {
public:
struct nested_class {
do_other_stuff() { ... }
};
};
using C = MyClass<A1, A2>;
the idea would be that C has it's nested class InnerClass that inherits A1::nested_class and A2::nested_class.
Would there be anything that could achieve such a thing? I personally can't figure out a way, but maybe it is possible.
Would inheritance hierarchy builders like Alexandrescu's Hierarchy Generators (which can be found in Loki: http://loki-lib.sourceforge.net/html/a00653.html) would be of any help?
thanks in advance if anyone has an idea.
To make InnerClass derived from all nested_classes, you should use Classes::nested_class... pattern:
#include <iostream>
#include <type_traits>
template <class... Classes>
class Myclass
{
public:
class InnerClass: public Classes::nested_class...
{
};
};
class A1 {
public:
struct nested_class {
void do_stuff() { /*...*/ }
};
};
class A2 {
public:
struct nested_class {
void do_other_stuff() { /*...*/ }
};
};
int main()
{
using Class = Myclass<A1, A2>;
std::cout << std::is_base_of<A1::nested_class, Class::InnerClass>::value << std::endl;
std::cout << std::is_base_of<A2::nested_class, Class::InnerClass>::value << std::endl;
return 0;
}