0

I am trying to create a map containing constructor functions. In order to do that I am using this method:

automatic registration of object creator function with a macro

So in a DLL I have data structures like that:

namespace pods
{


struct PODS_API StructExample{
    double  d;
    bool    b;
    int     i;
    StructExample() : d(0), b(false), i(0) {};
    StructExample(QList<QVariant> paramList) : 
        d(paramList[0].toDouble()), 
        b(paramList[1].toBool()), 
        i(paramList[2].toInt())
    {};
    StructExample(double param_d, bool param_b, int param_i) : d(param_d), b(param_b), i(param_i) {};
};
REGISTER_VARIABLE_TYPE(StructExample);
}

I am trying to make a Factory which will call the right constructor (implementing the right structure).

Those structures are contained in an object I call VariableT. This is a template class like that:

namespace variable{

template <class T>
class VariableT : public AbstractVariableT<T>, public IVariable {

public:
VariableT() {};
VariableT(const QString& name, const QList<QVariant> listParam) : name(name), item(T(listParam)) {};

~VariableT(){};

T* getData()
{
    return &item;
};

void setData(T* t)
{
    item = *t;
};


private:
T item;

};

}

When calling VariableT with the right T (i.e. StructExample) I can implement a container for those structures. VariableT inherit from IVariable so I can then use reference to those containers as IVariable in any map in my program.

Now I am trying to make a function inspired from the example I quoted before.

This will allow me to add structures and use them in my program with a minimum of code change.

I made my VariableT (container of struct) inherit from AbstractVariableT.

namespace variable
{

#define REGISTER_VARIABLE_TYPE(T) bool isRegistered_##T =     \
VariableFactory::instance()->                                 \
regVariable<T>(#T,  (VariableT<T>::createVariable)(const QString&, const QList<QVariant>&));

template <class T>
class  AbstractVariableT : public QObject
{
public:
static IVariable* createVariable(const QString& name, const QList<QVariant>& listParam) { return new VariableT<T>(name,listParam); }

virtual ~AbstractVariableT(){};


protected: 
QString name;

};

}

In this class I'm using a function createVariable to call the constructor methods of VariableT. Since AbstractVariableT is a template class, depending on the type of Struct used it will call a different constructor.

In order to call the createVariable function I am using a class I called VariableFactory:

namespace variable
{

class  VariableFactory
{

public:

static VariableFactory* instance();


static IVariable* createVariable(const QString& idVariable, const QString& name, const QList<QVariant>& listParam);

template <class T>
bool regVariable(const QString& idVariable, IVariable* (*creator)(const QString&, const QList<QVariant>&))
{
    variableCreators[idVariable] = creator;
    return true;
}


private:
QMap<QString, IVariable* (*)(const QString&, const QList<QVariant>&)> variableCreators;
};
}

In this class I store a map called variableCreator of my CreateVariable methods. (i.e. one map key/value will be :

"StructExample"/AbstractVariableT::CreateVariable<StructExample>(const QString& name, const QList<QVariant>& listParam);   

or something like that.. ).

In order to add constructor in the map I am using the function regVariable.

In order to automaticaly add every constructor for different StructContainer I want to use a macro which will call regVariable.

#define REGISTER_VARIABLE_TYPE(T) bool isRegistered_##T = VariableFactory::instance()->regVariable<T>(#T,  (VariableT<T>::createVariable)(const QString&, const QList<QVariant>&));

And I used this in my factory (depending on my type it get me the correct function from my map and use those parameters for the function :

IVariable* VariableFactory::createVariable(const QString& typeVariable, const QString& name, const QList<QVariant>& listParam)
{
    return instance()->variableCreators[typeVariable](name, listParam);
}

I can't find the correct syntax to do it. Or can I even do it this way ?

When I try to use the macro under my Struct (StructExample). I get different errors.

It looks like I can't register the constructor correctly :

Error   1   error C2653: 'VariableFactory' : is not a class or namespace name   
Error   5   error C2275: 'pods::StructExample' : illegal use of this type as an expression  
Error   2   error C2227: left of '->regVariable' must point to class/struct/union/generic type  
Error   8   error C2143: syntax error : missing ')' before 'const'  
Error   4   error C2065: 'VariableT' : undeclared identifier    
Error   7   error C2065: 'createVariable' : undeclared identifier   
Error   9   error C2059: syntax error : ')' 
Error   3   error C2039: 'VariableT' : is not a member of 'variable'    
Error   6   error C2039: 'createVariable' : is not a member of '`global namespace'' 
Error   10  error C1903: unable to recover from previous error(s); stopping compilation 

This question was edited.

Thanks for helping. Eric

Community
  • 1
  • 1
EricB
  • 1
  • 1
  • It's unclear what you are asking, can you provide an [SSCCE](http://sscce.org)? (And just a guess: Should `VariableT` be `Variable##T` in your macro?) – Daniel Frey Dec 19 '14 at 10:58
  • Hello Daniel, thank you for trying to help. Unfortunately I can't provide an SSCCE. But I'll try to make it clearer. – EricB Dec 19 '14 at 14:22
  • Okay edit done, its a bit long. I hope you can understand better my problems. Again, any help is welcome. Regarding Variable##T its not that. I have actually a class called VariableT. – EricB Dec 19 '14 at 15:28

0 Answers0