Какие аргументы я должен использовать, когда мне нужно специализировать имя типа, которое я объявил в своем классе-шаблоне?

У меня есть класс шаблона для потокобезопасного вектора:

template <class T>
class SharedVector {
    std::vector<T> vect;
    CRITICAL_SECTION cs;
    SharedVector(const SharedVector<T>& rhs) {}
public:
    typedef typename std::vector<T>::size_type SizeType;
    SharedVector();
    void PushBack(const T& value);
    void PopBack();
    SizeType size();
    const T& operator[](int index);
    void erase(int index);
    void Lock(); 
    void Unlock(); 
    virtual ~SharedVector();
};

Затем я хочу использовать его в своем диспетчере клиентов для TCP-сервера, чтобы делегировать некоторые обязанности от диспетчера клиентов этому вектору:

class TCPClientManager {
    TCPClientManager(const TCPClientManager&) {}
    TCPClientManager& operator=(const TCPClientManager&) {}
    SharedVector<Connection*> connections;
public:
    TCPClientManager();
    SharedVector<>::SizeType size(); //here is the problem
    void addConnection(const Client&); 
    void breakConnection(int); 
    void deleteConnection(int); 
    void Lock();
    void Unlock();
    ~TCPClientManager();
};

typename SharedVector<>::SizeType TCPClientManager::size() {
    return connections.size();
}

Мне нужно объявить тип извлекаемого значения. Компилятор сказал, что для шаблона слишком мало аргументов.


person chester89    schedule 26.01.2009    source источник


Ответы (2)


Вы должны предоставить аргумент типа для шаблона SharedVector:

SharedVector<Connection*>::SizeType size(); 
....
SharedVector<Connection*>::SizeType TCPClientManager::size() {
    return connections.size();
}

Поскольку этот тип Connection* не является параметром шаблона в TCPClientManager, а явно выбранным типом, вам не нужно ставить typename перед SharedVector<Connection*>::SizeType.

person Johannes Schaub - litb    schedule 26.01.2009

(Помимо литб, правда)

Вы должны указать свой контейнер; то есть typedef SharedVector<Connection*> ConnectionPool;. Это позволит вам написать ConnectionPool::size_type.

Примечание: container::size() должен возвращать container::size_type, а не container::SizeType. Это делает контейнер STL-совместимым. По той же причине класс итератора должен быть container::iterator, добавление элементов производится по container::push_back(container::value_type const&) и т.д.

person MSalters    schedule 27.01.2009