Специализация шаблона над производным классом - PullRequest
0 голосов
/ 22 июня 2011

Я не знаю, возможно ли это, я проверил StackOverflow, я нашел много вещей, но ничего, что действительно соответствует моей проблеме (или я не вижу отношения).Я хотел бы сделать что-то вроде этого:

class Bean
{
    public:
    Bean(){}
virtual ~Bean(){}
    template <class T>
    bool set_(T){return false;}
    template <class T>
    bool get_(T&){return false;}
};
template <class T>
class GenericBean: public Bean
{
    protected:
    T type;
};
class Prova :  public GenericBean<int>
{
    public:
      Prova(){type = 0;}

   template<int> bool set_(int value){ type=value;}
   template<int> bool get_(int& value){value = type;}

};

Я хотел бы иметь объект типа Prova, привести к Bean и получить специализированную функцию. Я хочу сделать что-то вроде этого:

#include <vector>
#include "Bean.h"

using namespace std;
class VirtualMessage
{
public:
    VirtualMessage(void){}
    virtual ~VirtualMessage(void){} 

    template <class ReturnValue, class Item>
    bool Get(ReturnValue & val)
    {
            for(size_t i = 0; i < m_vData.size(); i++)
            {
                if(m_vData[i].get_<ReturnValue>(val))
                  return true;
            }
    }
    template <class Item, class Value>
    bool Set(Value val)
    {
         Item bean;
         if(bean.set_<Value>(val))
         {
           m_vData.push_back(bean);
           return true;
         }
         return false;
     }
protected:
     vector<Bean> m_vData;
};

Main:

#include "VirtualMessage.h"
#include "Bean.h"
int main()
{
    VirtualMessage msg;
    if(msg.Set<Prova ,int>(4))
        printf("Test 1 passed");
}

этот код не компилируется

Возможно, никто не будет его использовать, но я написал что-то, что соответствует моим потребностям.Это не идеально, я должен работать над этим, но это начало:

#define UNIQUE(T)   unsigned int GetID(){return UniqueType<T>::id();}

struct UniqueTypeBase 
{ 
   static unsigned int _ids; 
}; 

unsigned int UniqueTypeBase::_ids = 0; 
template <class T> 
struct UniqueType : public UniqueTypeBase 
{ 
   static const unsigned int id() 
   { 
      static unsigned int typeId = 0; 
      if (typeId == 0) 
         typeId = ++_ids; 
      return typeId; 
    } 
 }; 


template <class T>
class TemplateBean
{
  public:
     T m_tValue;
     template<class T> set_(T){return false;}
     template<class T> get_(T&){return false;}

     bool set_(T value){    m_tValue    =   value;      return true;}
     bool get_(T& value)    {   value       =   m_tValue;return true;}
};

class Prova :  public TemplateBean<int>
{
public:
    UNIQUE(Prova)
    Prova(){m_tValue = 0;}
};
class Prova2 :  public TemplateBean<float>
{
   public:
     UNIQUE(Prova2)
     Prova2(){m_tValue = 0;}
};


class VirtualMessage
{
  public:
    VirtualMessage(void){}
    virtual ~VirtualMessage(void){} 
    template <class Item, class ReturnValue>
      bool Get(ReturnValue & val)
    {
         Item a;
         map<unsigned int, void*>::iterator it;
         it = m_TagMap.find(a.GetID());
         if(it != m_TagMap.end())
         {
             Item*  pItem = reinterpret_cast<Item*>(it->second);
             if(pItem->get_(val))
                return true;
          }
          return false;
     }
    template <class Item, class Value>
     bool Set(Value val)
    {
      Item* pBean = new Item();
      if(pBean->set_(val))
      {
           m_TagMap[pBean->GetID()] = (void*)pBean;     
           return true;
      }
      return false;
  }
  protected:
    map<unsigned int, void*> m_TagMap;
 };

Test Main:

 int main()
 {
    VirtualMessage msg;
    if(msg.Set<Prova ,int>(4))
        printf("Test 1 passed\n");
    if(!msg.Set<Prova,float>(4.00))
        printf("Test 2 succed\n");
    if(msg.Set<Prova2,float>(4.00))
        printf("Test 3 succed\n");
    int a=0;
    if(msg.Get<Prova>(a))
         printf("%d = 4...if 4=4 test passed\n",a);
     float b=0;
    if(msg.Get<Prova2>(b))
        printf("%f = 4...if 4=4 test passed\n",b);
    getchar();
  }

1 Ответ

3 голосов
/ 22 июня 2011

Я думаю, что вы неправильно поняли использование шаблонов.

Шаблоны - это чертежи для построения классов или методов, которые компилятор использует для создания реальных классов и методов (что называется созданием экземпляров).

Как таковые, они являются просто средством времени компиляции.Следовательно, они не могут быть virtual, и, таким образом, перегружать шаблонный метод в производном классе не означает, что вы ожидаете.Он скрывает метод базового класса, когда используется из производного (статически), но вы все равно вызываете метод базового класса, если используете ссылку или указатель на базовый класс.

Что вы пытаетесь сделатьС шаблонами, к сожалению, невозможно добиться: требуется проверка во время выполнения.

Кроме того, вы используете std::vector<Bean>, который не будет работать должным образом.Полиморфные типы не должны обрабатываться значениями в C ++, вам нужен std::vector< std::unique_ptr<Bean> > или boost::ptr_vector<Bean> ...

Я бы порекомендовал прочитать хороший учебник по C ++, прежде чем пытаться выполнить задачу, которую вы перед собой поставили.Вам нужно базовое введение в парадигмы C ++ ... и ошибки.И есть много ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...