передать ссылку на шаблонный класс в нешаблонный
От: ksd Россия  
Дата: 16.07.18 13:32
Оценка:
Есть вот такое:
template <class T>
class Base
{
    std::set<T*> subscribers;
    CriticalSection cs;
public:
    void Lock() {
        cs.Enter();
    }

    void Unlock() {
        cs.Leave();
    }

    void Subscribe(T* s) {
        subscribers.insert(s);
    }

    void UnSubscribe(T* s) {
        subscribers.erase(s);
    }
};

struct Intf
{
    virtual void OnSomeEvent() = 0;
};

class Foo: public Base<Intf>
{
    static void callback(foo* f) {
        f->Lock();
        for (std::set<Intf*>::const_iterator it = f->subscribers.begin(); it != f->subscribers.end(); ++it) {
                    it->OnSomeEvent();
            }
        f->Unlock();
    }
};

class Bar: private Intf
{
public:
    Bar(Foo* f) {
        f.Subscribe(this);
`    }
    void OnSomeEvent() override {
        doSome();
    }
};


как бы так сделать scope guard для foo::callback, чтобы не тащщить везде Intf? т.е. если сделать, например, так:
template < class T >
class BaseGuard
{
    Base<T>& b_;
public:
    BaseGuard(Base<T>& b) : b_(b) {
        b.Lock();
    }
    ~BaseGuard() {
        b_.Unlock();
    }
};

то использование получается такое:
class Foo: public Base<Intf>
{
    static void callback(foo* f) {
        BaseGuard<Intf> bg(*f);
        for (std::set<Intf*>::const_iterator it = f->subscribers.begin(); it != f->subscribers.end(); ++it) {
                    it->OnSomeEvent();
            }
    }
};

вот этот вот <Intf> не нравится.


Примечание. Лучше всего, чтобы код собирался в 2008 студии, но можно и без этого условия.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.