Templated Function results in Circular Inclusion - c++

I have a tricky circular inclusion issue that I dont know how to solve. To sum up:
IApp inherits from Component
Component implements a templated function in its header file that uses IApp::registerForEvent
What technique or method can I use to fix/avoid this circular inclusion?
class Component;
class IApp;
class Component
{
IApp* app;
// Error: Invalid use of incomplete type 'class IApp'
template<typename T>
void registerEvent(const int& evtId, Status (T::*func) (int))
{
auto res = std::bind(func, (T*)this, std::placeholders::_1);
app->registerForEvent(evtId);
}
};
class IApp : public Component
{
public:
void registerForEvent(const int& evtId)
{
printf("IApp::registerForEvent\n");
// ...
}
};

Define registerEvent after IApp.
class IApp;
class Component
{
IApp* app;
template<typename T>
void registerEvent(const int& evtId, Status (T::*func) (int));
};
class IApp : public Component {
...
};
template <typename T>
Component::registerEvent(const int& evtId, Status (T::*func) (int)) {
auto res = std::bind(func, (T*)this, std::placeholders::_1);
app->registerForEvent(evtId);
}
If need be, also define A::registerEvent after Component::registerEvent.

You are trying to use a derived class in it's base class, which doesn't seem like a good design approach to me. I would suggest moving it to some other class, which both classes have access to.

Your are aggregating a Derived class object. Your may thus solve the circular dependence with the curiously recurring template pattern?
template <typename Aggregated>
class Component
{
Aggregated* app;
template<typename T>
void registerEvent(const int& evtId, Status (T::*func) (int))
{
auto res = std::bind(func, (T*)this, std::placeholders::_1);
app->registerForEvent(evtId);
}
};
class IApp : public Component<IApp>
{
public:
void registerForEvent(const int& evtId)
{
printf("IApp::registerForEvent\n");
// ...
}
};
Still, it is not clear to me what you are trying to do. For one you assume the function passed Component::registerEvent is a member of Component (you bind to (T*)this) whilst delegating the Event ID to the aggregated IApp. To me it seems rethinking your design may solve also the circular dependence problem?

Related

C++/(Qt) pointer to any object with specific method

How do I do to call a specific method present on all classes from an other (TranslationManager) class ?
I simplified a lot the code. I just want to call the setTranslationText of any class from TranslationManager.
These are to take in consideration:
All classes have a setTranslationText method
We should call setTranslationText of any class from TranslationManager by using the pointer to the class
class Interface
{
...
public:
void setTranslationText(QString translatedString);
}
class AnyOtherInterface
{
...
public:
void setTranslationText(QString translatedString);
}
...
…
Translationmanager::Translationmanager(){
AnyClass = Interface; // Pointer to Interface Class
AnyClass->setTranslatioNText("Text");
AnyClass = AnyOtherInterface; // Pointer to AnyOtherInterface Class
AnyClass->setTranslatioNText("AnotherText");
}
…
You could use a template
template <typename T>
void setTranslationText(T* t, const QString &translatedString)
{
t->setTranslationText(translatedString);
}
That way you wouldn't need an interface class just to inherit for this one (or however many) methods. Then the template would only compile if for a given class instantiation they had a setTranslationText method defined. The way you'd use it is
Translationmanager::Translationmanager()
{
setTranslationText(Interface, "Text"); // Pointer to Interface Class
setTranslationText(AnyOtherInterface, "AnotherText"); // Pointer to AnyOtherInterface Class
}
Adding to Cory's answer: If you're using C strings to initialize QString, you shouldn't depend on the implicit conversion - instead, make your use case explicit:
template <typename T>
void setTranslationText(T* t, const char *translatedString) {
t->setTranslationText(QString::fromUtf8(translatedString));
}
I wasn't precise about what I wanted. I finally found the best solution to my problem: callback.
Solution found on: C++ class member callback simple examples
std::vector<std::function<void(std::string,std::string)>> callbacks;
template<class T> void addTranslationText(T* const object, void(T::* const mf)(std::string,std::string)){
using namespace std::placeholders;
callbacks.emplace_back(std::bind(mf, object, _1, _2));
}
...
// Call callback
callbacks.at(0)(std::string("arg1"), std::string("arg2"));

Error using boost::bind

Lets say I have an array of functions :
name::Function _actions[10];
The name::Function is just a wrapper for std::function:
class Function{
public :
std::function<void(float dt)> Function;
void exec(float dt){
Function(dt);
}
};
And now I have a function to make it generic so it can bind any classes functions :
template<class T>
void bindFunction(int action,void (T::*function)(float) , T* classPtr)
{
_actions[action] = boost::bind(&function, this, boost::placeholders::_1);
}
And want to use it inside a class that inherits this method (the base class is generic but I think it shouldn´t be a problem)
DefaultMovableEntity()
{
bindFunction(1, &DefaultMovableEntity::func1, this);
}
void func1(float dt)
{
//Code
}
However I keep getting erros :
What is the main problem? I thought im doing everything right. Thanks.
Edit1
After removing the & from the function and replacing this got following error:
There are several problems with your code:
You can't assign your bind result to the array since your array member type is Function, not std::function.
You need to remove & as said before in comments.
Your member named Function is same as class name so compiler may think you are trying to call class constructor.
The following code should work:
class Function {
public:
std::function<void(float)> func;
void exec(float dt) {
func(dt);
}
};
and bindFunction code:
template<class T>
void bindFunction(int action, void (T::*function)(float), T* classPtr)
{
_actions[action].func = boost::bind(function, classPtr, boost::placeholders::_1);
}
However I would suggest slight improvement of Function class so that it doesn't expose its members directly:
class Function
{
private:
std::function<void(float)> func;
public:
Function() = default;
Function(std::function<void(float)> f) : func(f) { }
void exec(float dt) {
func(dt);
}
};
And corresponding change of your bindFunction:
template<class T>
void bindFunction(int action, void (T::*function)(float), T* classPtr)
{
_actions[action] = Function(boost::bind(function, classPtr, boost::placeholders::_1));
}

Refactoring using Abstract Base Classes and Templates in C++

I have a problem with some refactoring I am attempting. We have a lot of code duplication and I am trying to sort this out. I have the following class structure
IMessageSink.h:
class IMessageSink
{
public:
virtual ~IMessageSink() { };
virtual void process(const taurus::Msg& msg) = 0;
};
I have the following base class ModelBase.h which all models must inherit from, at this point please not the use of the friend class EM:
class ModelBase : public virtual IMessageSink
{
public:
ModelBase(Tag a);
void process(const taurus::Msg& msg);
void reset();
private:
friend class EM; // I will ask about this below.
virtual void calculate(double lambda) = 0;
};
The implementation of friend EM is not correct and I ask about this below. I then have a class that implements/inherits from ModelBase, ModelM0.h:
class ModelM0 : public virtual ModelBase
{
public:
ModelM0(Tag a);
static ModelM0* ModelM0::make(Tag a)
{
ModelM0* m = new ModelM0(a);
m->reset();
return m;
}
private:
void calculate(double lambda);
};
with ModelM0.cpp implemented as:
ModelM0::ModelM0(Tag a) : ModelBase(a) { }
void ModelM0::calculate(double lambda)
{
// Do stuff.
}
The problem is with the EM friend class and how to implement this in a generic fashion. Previously, this class only worked with types ModelM0 which did not inherit from ModelBase. Now other models also inherit from ModelBase and EM needs to work with these as well - here lies the problem. I have the following definition in EM.h (which I have changed to a template so we can specify the type of ModelBase we are using TModel):
with EM.h as:
template <class TModel>
class EM : public virtual IMessageSink
{
public:
static EM* make(Tag a)
{
return new EM(a);
}
EM(Tag a);
~EM();
void process(const taurus::Msg& msg);
void run();
private:
struct Bucket
{
TModel* _model;
std::vector<TinyMatrix<1, 1> > _obs
};
EM::Bucket& getModel(int ag);
}
The problem implementation is EM::Bucket& getModel(int ag);, in EM.cpp we have
template<class TModel>
EM<TModel>::EM(Tag a) { }
template<class TModel>
EM<TModel>::~EM()
{
run();
}
template<class TModel>
void EM<TModel>::process(const taurus::Msg& msg)
{
int ag = getMessageCount(msg.type()); // External call.
if (ag <= 3)
{
Bucket& b = getModel(ag);
TModel* m = b._model;
m->process(msg);
}
}
The above seems to be okay, my problem is the implementation of getModel
template<class TModel>
EM<TModel>::Bucket& EM<TModel>::getModel(int ag)
{
// This is not right.
TModel* m;
m = TModel::make(getTag(ag)); // This is not right - I need a factory.
// ... Do stuff.
Bucket& b = // Get a bucket.
b._model = m;
return b;
}
My questions:
How can I change the above code so that in EM<TModel>::getModel(int ag) I can create the correct TModel using make in the above - do I need a factory and how would this be implemented?
In ModelBase.h the EM class is specified as a friend class. How can this me made generic to work with the TModel (ModelBase) type being used?
It is important to note here that this is a refactoring question, not whether-or-not the code I have shown in the methods is proper or correct (this has been cut down in order to succinctly highlight my problems). The refactoring is the only thing I would like help with. Thanks very much for your time.
When I tried to get your code compiling, I had to fix a few missing semicolons and missing types (Tag, taurus::Msg, TinyMatrix) and also fix the declaration and definition of getModel(int ag)
Generally, you need to indicate to the compiler, that Bucket is actually a type name and not some other sort of parameter.
For the declaration you have 2 options:
Bucket& getModel(int ag); // (1)
typename EM<TModel>::Bucket& getModel(int ag); // (2)
(1) is implicit usage of the Bucket type of your current template specialization. (2) is explicit type usage together with the typename keyword for the compiler, as mentioned above.
For the definition, you definitely need to typename keyword, since you are out of your class definition context.
template<class TModel>
typename EM<TModel>::Bucket& EM<TModel>::getModel(int ag)
{
// This is not right.
TModel* m;
m = TModel::make(getTag(ag)); // This is not right - I need a factory.
// ... Do stuff.
Bucket& b = // Get a bucket.
b._model = m;
return b;
}
Just ignore the "This is not right." comments - I copied them over from your sample code. Its actually perfectly right.
For the friend declaration, you need to add a template version, since you want to befriend all possible template instantiations. I looked it up from this answer (Credits to Anycorn)
template <class> friend class EM;
Hope that solves all your issues. Note I used template <class> since you used it. Personally I prefer template <typename>.

Is it appropriate to emulate templated data members?

I'm trying to implement a variation of the Observer pattern that buffers different event types and came to an impasse.
This is what I'm trying to go for:
class Foo
{
/* ..... */
std::vector<Base*> buf;
template<typename T>
void newEvent(T ev)
{
/* I give the list of observers to each event.
* There are billions of events coming in for
* each run of the application
*/
buf.push_back(new Event<T>(ev, &observers<T>));
}
/* Illegal, templated data members */
template<typename T>
std::vector<Observer<T>*> observers;
template<typename T>
void attach(Observer<T> obs)
{
/* Each type has its own list of observers */
observers<T>.push_back(obs);
}
/* ..... */
};
Later on when the buffer is flushed...
void Foo::flush()
{
for (Base* ev : buf)
{
ev->notifyAll();
delete ev;
}
}
template <typename T>
class Event : public Base
{
/* ..... */
Event(T t, const std::vector<Observer*>& o):observers(o),payload(t){}
void notifyAll()
{
for (Observer* obs : observers)
obs->onNotify(this->payload);
}
};
The type from the template is just a POD coming in from the outside. When it gets packaged up, I give it the list of observers. Now I could just manually define each type of observer vector in Foo, but I want to be able to support an undefined number of 'Event' types.
I know templated data members of a class are illegal, even in c++14 where there is some more support templated variables.
Does it make sense to keep going down this path? Originally I had the "observers" part statically in each 'Event' type, but I'm trying to get rid of as much global state as I can, for testability.
I'm trying to just move things into a class template, instead, but then I'm having trouble there, too.
template <typename T>
class EventHandler //can't think of a good name for this demon baby
{
public Base* create(T t); //when I create a new event, I need the observer list
public void attach(Observer<T>);
private std::vector<Observer<T>*> observers;
};
class Buffer
{
/* ..... */
EventHandler<EventType1> thing1;
EventHandler<EventType2> thing2;
EventHandler<EventType3> thing3;
template<typename T>
public newEvent(T ev) //I could just explicitly say the type here
{
buf.push_back(thing?.create(ev)); //how to know which one to use?
}
};
I run into the same problem from the other angle :/. I also thought about just switching on the type id but thought it was messy.
One way would be using std::type_index:
class event_handler_base{
public:
virtual ~event_handler_base(){}
};
template<typename T>
class event_handler: public event_handler_base{
public:
void handle(T ev){ /* handle event */ }
};
class my_special_class{
public:
~my_special_class(){
for(auto &&p : handlers)
delete p.second;
}
template<typename T>
void new_event(T ev){
get_handler<T>().handle(ev);
}
template<typename T>
event_handler<T> &get_handler(){
static std::type_index ti(typeid(T));
auto it = handlers.find(ti);
if(it == handlers.end())
it = handlers.emplace(ti, new event_handler<T>()).first;
return dynamic_cast<event_handler<T>&>(*it->second);
}
std::unordered_map<std::type_index, event_handler_base*> handlers;
};
I wouldn't prefer this method if you can figure out a compile-time answer, but it is still interesting. Always prefer compile time cost over run time cost.

recursive c++ template problem

Say I have a template class that takes msgs from source, does something smart to them, and then sends them to a sink:
template <typename Source, typename Sink>
class MsgHandler
{
MsgHandler(Source* pSource)
: m_pSource(pSource)
{
m_pSource->setHandler(this);
}
};
//Now the definition of the Source:
template <typename Handler>
class Source
{
void setHandler(Handler* pHandler)
{
m_pHandler = pHandler;
}
};
All fine, but now I can't really make a Source or Handler. Eg:
MsgHandler<FileSource<MsgHandler<FileSource.... recursing parameters...
FileSource<MsgHandler<FileSource<MsgHandler.... same problem when trying to build a source
Is there a way to solve this problem without using a virtual base class for the Handler?
Virtual base class solution:
class MyHandler
{
virtual ~MyHandler() {};
virtual void handleSomething() = 0;
};
template <typename Source, typename Sink>
class MsgHandler : public MyHandler
{
MsgHandler(Source* pSource)
: m_pSource(pSource)
{
m_pSource->setHandler(this);
}
void handleSomething() {}
};
class Source
{
void setHandler(MyHandler* pHandler)
{
m_pHandler = pHandler;
}
};
You could use a templated parameter for the source parameter of your handler:
class MySink;
template <template<typename Handler> class Source, typename Sink>
class MsgHandler
{
Source<MsgHandler>* m_pSource;
MsgHandler(Source<MsgHandler>* pSource)
: m_pSource(pSource)
{
m_pSource->setHandler(this);
}
};
//Now the definition of the Source:
template <typename Handler>
class Source
{
void setHandler(Handler* pHandler)
{
m_pHandler = pHandler;
}
};
//Now you can define variables like this
MsgHandler<Source, MySink> myHandler;
Of course that requires the Source parameter of MsgHandler to be a template with exactly one parameter (the handler), but if you can live with that constraint this would solve your definition problem (otherwise you might (or might not depending on what exactly you would be trying) be able to use some extra template foo to circumvent this restriction (creating another template which takes the handler as parameter and has a typedef for the corresponding SourcesType comes to mind).
In this scenario it might also be a good idea to add an typedef Source<MsgHandler> SourceType to MsgHandler to make the Source-Instantiation visible to the caller (instead of requiring the programmer to guess that MsgHandler will instantiate Source.
I don't understand why your Source needs to be parameterized on its handler. If Source and Handler really do need to be tightly coupled in the way you describe, it does not seem like templates buy you very much beyond interface definition. Seems to me like you could just have a non-template Source class that encapsulates Handler<Source, Sink>.
It looks like the Handler shouldn't know anything about the Source. How about simple linear dependency:
template <typename Sink>
class Handler {
private:
Sink* sink; // get this pointer in the constructor?
public:
void handle( const Msg& m ) {
// processing
sink->accept( m );
}
};
template <typename Handler>
class Source {
private:
Handler* handler;
public:
void genMessage() {
Msg m;
// get message off the wire?
handler->handle( m );
}
};
Could also be twisted to have "handling" and "sinking" as policies.