Шаблонная виртуальная ыункция
От: Аноним  
Дата: 26.02.13 12:43
Оценка:
Здравствуйте коллеги, знаю что нельзя явно определить шаблонную функцию виртуальной, но хотелось бы получть что то типа такого


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, но можно ли как то "перегрузить", что бы через указатель базового классы вызывался шаблонный метод потомка?
Re: Шаблонная виртуальная ыункция
От: rg45 СССР  
Дата: 26.02.13 13:13
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте коллеги, знаю что нельзя явно определить шаблонную функцию виртуальной, но хотелось бы получть что то типа такого

А>[...]
А>В моем примере естественно происходит вызов методов класса A, но можно ли как то "перегрузить", что бы через указатель базового классы вызывался шаблонный метод потомка?

Да, виртуальная функция не может быть шаблонной, но зато шаблонным может быть весь класс потомка. Может, это поможет?
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: Шаблонная виртуальная ыункция
От: Ventalf Россия  
Дата: 26.02.13 13:55
Оценка:
Здравствуйте, Аноним, Вы писали:

> Здравствуйте коллеги, знаю что нельзя явно определить шаблонную функцию виртуальной

> ...
> В моем примере естественно происходит вызов методов класса 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;
}
avalon 1.0rc3 build 432, zlib 1.2.7
Re[2]: Шаблонная виртуальная ыункция
От: Ventalf Россия  
Дата: 27.02.13 09:50
Оценка:
Здравствуйте, 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;
}
avalon/1.0.432
Re: Шаблонная виртуальная ыункция
От: Константин Россия  
Дата: 27.02.13 10:48
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте коллеги, знаю что нельзя явно определить шаблонную функцию виртуальной, но хотелось бы получть что то типа такого

А>В моем примере естественно происходит вызов методов класса A, но можно ли как то "перегрузить", что бы через указатель базового классы вызывался шаблонный метод потомка?

Может быть проще и вообще обойтись без наследования?

class A
{
public:
    A(){}
    virtual ~A(){std::cout <<"~A()";}

    template<class _TAggrKey, class _TMemSet>
    bool LoadBTreeNode(_TMemSet& Set)
    {
        for( const auto& key, getData() )
          Set.insert(key);
    }
    void setData( const std::vector<int>& data) {...}
    const std::vector<int>& getData() const { ...}

private:
};


Ну или так, основная идея — вынести зависимость от типа шаблона из виртуальной функции:

class A
{
public:
    A(){}
    virtual ~A(){std::cout <<"~A()";}

    template<class _TAggrKey, class _TMemSet>
    bool LoadBTreeNode(_TMemSet& Set)
    {
        for( const auto& key, getData() )
          Set.insert(key);
    }

private:
    virtual const std::vector<int>& getData() const = 0;
};

class B : public A
{
public:
    B()
    {
      data_.push_back(12);
    }
    virtual ~B( ){std::cout <<"~B()"; }
    virtual const std::vector<int>& getData() const
    {
      return data_;
    }

    virtual int size() const
    {
        return data_.size();
    }

};
class C : public A
{
public:
    C()
    {
      data_.push_back(18);
      data_.push_back(22);
    }
    virtual ~C( ){std::cout <<"~C()"; }
    virtual const std::vector<int>& getData() const
    {
      return data_;
    }
    virtual int size() const
    {
        return data_.size();
    }
};

///////////////////////////////////////
    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;
Re[2]: Шаблонная виртуальная ыункция
От: B0FEE664  
Дата: 27.02.13 12:20
Оценка: -1
Здравствуйте, rg45, Вы писали:

R>Да, виртуальная функция не может быть шаблонной,

Исключительно из-за лени писателей компиляторов.

R>но зато шаблонным может быть весь класс потомка. Может, это поможет?

Без приведения типа не получится.
И каждый день — без права на ошибку...
Re[3]: Шаблонная виртуальная ыункция
От: Константин Россия  
Дата: 27.02.13 18:51
Оценка:
Здравствуйте, B0FEE664, Вы писали:

R>>Да, виртуальная функция не может быть шаблонной,

BFE>Исключительно из-за лени писателей компиляторов.

Может и к лучшему. Шаблоны и так катастрофически замедляют сборку. Если ещё и это реализовать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.