Есть ли элегантный способ определить имя типа по умолчанию в шаблоне

Я использую C ++ 98 здесь, к сожалению. Здесь я вставляю полный набор кодов

/*<class.h> begins

#ifndef INCLUDED_CLASS
#define INCLUDED_CLASS

#include <iostream>
#include <boost/shared_ptr.hpp>

class A
{
public:
A() { _a = 27; }
void print() const { std::cout << "A is " << _a << "." << std::endl; }
protected:
int _a;
};
typedef boost::shared_ptr<A> APtr;

class AA : public A
{
public:
void print() const { std::cout << "AA is " << _a << "!" << std::endl; }
};

class B
{
public:
B(double b) { _b = b; }
void print() const { std::cout << "B is " << _b << "." << std::endl; }
protected:
double _b;
};
typedef boost::shared_ptr<B> BPtr;

class BB : public B
{
public:
BB(double b) : B(b) {};
void print() const { std::cout << "BB is " << _b << "!" << std::endl; }
};

#endif

/*<class.h> ends/*<factory.h> begins

#ifndef INCLUDED_FACTORY
#define INCLUDED_FACTORY

#include <map>
#include <string>
#include <boost/shared_ptr.hpp>

template<class bT, class pT=void>
class Creator
{
public:
virtual bT* create() = 0;
virtual bT* create(const pT* param) = 0;
};

template <class bT, class pT>
struct CreatorPtr
{
typedef boost::shared_ptr< Creator<bT> > type;
};template <class bT, class cT, class pT>
class CreatorImpl : public Creator<bT, pT>
{
public:
virtual bT* create() { return new cT; }
virtual bT* create(const pT* param) { return new cT(param); }
};template<class bT, class pT=void>
class Factory
{
public:
virtual bT* create(const std::string& name) const = 0;
virtual bT* create(const std::string& name, const pT* param) const = 0;
protected:
Factory() {}
Factory(const Factory&) {}
Factory &operator=(const Factory&) { return *this; }
void registerCreator(const std::string& name, typename CreatorPtr<bT, pT>::type creator)
{ _table_creator[name] = creator; }
typedef std::map<std::string, typename CreatorPtr<bT, pT>::type> tableCreator;
typedef typename tableCreator::const_iterator citerTc;
citerTc begin() const { return _table_creator.begin(); }
citerTc end() const { return _table_creator.end(); }
citerTc find(const std::string& name) const { return _table_creator.find(name); }
protected:
tableCreator _table_creator;
};

class A;
class EngineA : public Factory<A>
{
public:
virtual A* create(const std::string& name) const
{
citerTc it = find(name);
if (it != end() && it->second)
{
return it->second->create();
}
else
return (A*)NULL;
}

static Factory<A>& get()
{
static EngineA instance;
instance.registerEngine();
return instance;
}
private:
virtual A* create(const std::string& name, const void* param) const { return (A*)NULL; }
private:
virtual void registerEngine();
};

void EngineA::registerEngine()
{
CreatorPtr<A, void>::type AACreator(new CreatorImpl<A, AA, void>);
registerCreator("AA", AACreator);
}

class B;
class EngineB : public Factory<B, double>
{
public:
virtual B* create(const std::string& name, const double* value) const
{
citerTc it = find(name);
if (it != end() && it->second && value)
{
return it->second->create(value);
}
else
return (B*)NULL;
}

static Factory<B, double>& get()
{
static EngineB instance;
instance.registerEngine();
return instance;
}
private:
virtual B* create(const std::string& name) const { return (B*)NULL; }
private:
virtual void registerEngine();
};

void EngineB::registerEngine()
{
CreatorPtr<B, double>::type BBCreator(new CreatorImpl<B, BB, double>);  // error 1
registerCreator("BB", BBCreator);
}

#endif

/*<factory.h> ends/*<main.cpp> begins

#include <class.h>
#include <factory.h>

int main(void)
{
APtr a(EngineA::get().create("AA"));
if (a)
a->print();

double value = 35.7;
BPtr b(EngineB::get().create("BB",&value));
if (b)
b->print();

return 0;
}

/*<main.cpp> ends

Цель состоит в том, чтобы иметь общую фабрику, основанную на шаблонах, чтобы она могла создавать класс, либо не требующий создания параметров, либо некоторого ввода (по типу pT).

Ошибки компиляции таковы:

1- error: cannot convert ‘CreatorImpl<B, BB, double>*’ to ‘Creator<B, void>*’ in initialization
2- error: no matching function for call to ‘BB::BB()’
./class.h:36: note: candidates are: BB::BB(double)
./class.h:34: note:                 BB::BB(const BB&)
3- error: no matching function for call to ‘BB::BB(const double*&)’
./class.h:36: note: candidates are: BB::BB(double)
./class.h:34: note:                 BB::BB(const BB&)
4- error: no matching function for call to ‘AA::AA(const void*&)’
./class.h:18: note: candidates are: AA::AA()
./class.h:18: note:                 AA::AA(const AA&)

Мои вопросы: 1. как устранить эти ошибки; 2. это хороший дизайн для создания абстрактной и универсальной фабрики?

Спасибо.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]