Здравствуйте коллеги, знаю что нельзя явно определить шаблонную функцию виртуальной, но хотелось бы получть что то типа такого
class A
{
public:
A(){}
virtual ~A(){std::cout <<"~A()";}
template<class _TAggrKey, class _TMemSet>
bool LoadBTreeNode(_TMemSet& Set)
{std::cout <<"A::LoadBTreeNode"; return true;}
virtual int size() const = 0;
};
class B : public A
{
public:
B(){}
virtual ~B( ){std::cout <<"~B()"; }
template<class _TAggrKey, class _TMemSet>
bool LoadBTreeNode(_TMemSet& Set)
{
std::cout <<"B::LoadBTreeNode";
_TAggrKey key;
key = 12;
Set.insert(key);
}
virtual int size() const
{
return 1;
}
};
class C : public A
{
public:
C(){}
virtual ~C( ){std::cout <<"~C()"; }
template<class _TAggrKey, class _TMemSet>
bool LoadBTreeNode(_TMemSet& Set)
{
std::cout <<"C::LoadBTreeNode";
_TAggrKey key;
key = 18;
Set.insert(key);
key = 22;
Set.insert(key);
}
virtual int size() const
{
return 2;
}
};
///////////////////////////////////////
A *pB = 0;
A *pC = 0;
pB = new B();
pC= new C();
std::set<int> setI;
std::set<float> setF;
pB->LoadBTreeNode<int, std::set<int> >(setI);
pC->LoadBTreeNode<float, std::set<float> >(setF);
delete pB;
delete pC;
В моем примере естественно происходит вызов методов класса A, но можно ли как то "перегрузить", что бы через указатель базового классы вызывался шаблонный метод потомка?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте коллеги, знаю что нельзя явно определить шаблонную функцию виртуальной, но хотелось бы получть что то типа такого А>[...] А>В моем примере естественно происходит вызов методов класса A, но можно ли как то "перегрузить", что бы через указатель базового классы вызывался шаблонный метод потомка?
Да, виртуальная функция не может быть шаблонной, но зато шаблонным может быть весь класс потомка. Может, это поможет?
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Аноним, Вы писали:
> Здравствуйте коллеги, знаю что нельзя явно определить шаблонную функцию виртуальной > ... > В моем примере естественно происходит вызов методов класса A, но можно ли как то "перегрузить", что бы через указатель базового классы вызывался шаблонный метод потомка?
Можно сделать так (предполагает наличие в сете типа value_type, константы кастятся в ключи статически):
#include <iostream>
#include <set>
class AbstractSetHolder
{
public:
virtual void insert(int key) const = 0;
virtual ~AbstractSetHolder() {}
};
template <class _TMemSet> class SetHolderImpl : public AbstractSetHolder
{
public:
SetHolderImpl(_TMemSet &set) : set_(set)
{}
virtual void insert(int key) const
{
set_.insert(static_cast<typename _TMemSet::value_type>(key));
}
private:
_TMemSet &set_;
};
class A
{
public:
A(){}
virtual ~A()
{
std::cout << "~A()" << std::endl;
}
virtual bool LoadBTreeNode(const AbstractSetHolder &set) const
{
std::cout << "A::LoadBTreeNode" << std::endl;
return true;
}
};
class B : public A
{
public:
B(){}
virtual ~B()
{
std::cout << "~B()" << std::endl;
}
virtual bool LoadBTreeNode(const AbstractSetHolder &set) const
{
std::cout << "B::LoadBTreeNode" << std::endl;
set.insert(12);
return true;
}
virtual int size() const
{
return 1;
}
};
class C : public A
{
public:
C(){}
virtual ~C()
{
std::cout << "~C()" << std::endl;
}
virtual bool LoadBTreeNode(const AbstractSetHolder &set) const
{
std::cout <<"C::LoadBTreeNode" << std::endl;
set.insert(18);
set.insert(22);
return true;
}
virtual int size() const
{
return 2;
}
};
int main(int, char **)
{
A *pB = 0;
A *pC = 0;
pB = new B();
pC = new C();
std::set<int> setI;
std::set<float> setF;
pB->LoadBTreeNode(SetHolderImpl<std::set<int> > (setI));
pC->LoadBTreeNode(SetHolderImpl<std::set<float> > (setF));
delete pB;
delete pC;
}
Здравствуйте, Ventalf, Вы писали:
V> > Здравствуйте коллеги, знаю что нельзя явно определить шаблонную функцию виртуальной V> > ... V> > В моем примере естественно происходит вызов методов класса A, но можно ли как то "перегрузить", что бы через указатель базового классы вызывался шаблонный метод потомка?
V> Можно сделать так (предполагает наличие в сете типа value_type, константы кастятся в ключи статически):
Или даже так:
#include <iostream>
#include <boost/unordered_set.hpp>
class AbstractSetHolder
{
public:
virtual void insert(int key) const = 0;
virtual ~AbstractSetHolder() {}
};
template <class _TMemSet> class SetHolderImpl : public AbstractSetHolder
{
public:
SetHolderImpl(_TMemSet &set) : set_(set)
{}
virtual void insert(int key) const
{
set_.insert(static_cast<typename _TMemSet::value_type>(key));
}
private:
_TMemSet &set_;
};
class A
{
public:
A(){}
virtual ~A()
{
std::cout << "~A()" << std::endl;
}
template<class _TMemSet> bool LoadBTreeNode(_TMemSet &set)
{
return LoadBTreeNodeImpl(SetHolderImpl<_TMemSet>(set));
}
virtual bool LoadBTreeNodeImpl(const AbstractSetHolder &set) const
{
std::cout << "A::LoadBTreeNode" << std::endl;
return true;
}
};
class B : public A
{
public:
B(){}
virtual ~B()
{
std::cout << "~B()" << std::endl;
}
virtual bool LoadBTreeNodeImpl(const AbstractSetHolder &set) const
{
std::cout << "B::LoadBTreeNode" << std::endl;
set.insert(12);
return true;
}
virtual int size() const
{
return 1;
}
};
class C : public A
{
public:
C(){}
virtual ~C()
{
std::cout << "~C()" << std::endl;
}
virtual bool LoadBTreeNodeImpl(const AbstractSetHolder &set) const
{
std::cout <<"C::LoadBTreeNode" << std::endl;
set.insert(18);
set.insert(22);
return true;
}
virtual int size() const
{
return 2;
}
};
int main(int, char **)
{
A *pB = 0;
A *pC = 0;
pB = new B();
pC = new C();
boost::unordered_set<int> setI;
pB->LoadBTreeNode(setI);
std::set<float> setF;
pC->LoadBTreeNode(setF);
delete pB;
delete pC;
}
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте коллеги, знаю что нельзя явно определить шаблонную функцию виртуальной, но хотелось бы получть что то типа такого А>В моем примере естественно происходит вызов методов класса A, но можно ли как то "перегрузить", что бы через указатель базового классы вызывался шаблонный метод потомка?
Может быть проще и вообще обойтись без наследования?
Здравствуйте, rg45, Вы писали:
R>Да, виртуальная функция не может быть шаблонной,
Исключительно из-за лени писателей компиляторов.
R>но зато шаблонным может быть весь класс потомка. Может, это поможет?
Без приведения типа не получится.