Использование шаблонного параметра value_type - PullRequest
15 голосов
/ 10 ноября 2011

Как можно использовать тип_стандартного контейнера?
Я пытался использовать это так:

#include <vector>

using namespace std;

template <typename T>
class TSContainer {
private:
        T container;
public:
        void push(T::value_type& item)
        {
                container.push_back(item);
        }
        T::value_type pop()
        {
                T::value_type item = container.pop_front();
                return item;
        }
};
int main()
{
        int i = 1;
        TSContainer<vector<int> > tsc;
        tsc.push(i);
        int v = tsc.pop();
}

Но это приводит к:

prog.cpp:10: error: ‘T::value_type’ is not a type
prog.cpp:14: error: type ‘T’ is not derived from type ‘TSContainer<T>’
prog.cpp:14: error: expected ‘;’ before ‘pop’
prog.cpp:19: error: expected `;' before ‘}’ token
prog.cpp: In function ‘int main()’:
prog.cpp:25: error: ‘class TSContainer<std::vector<int, std::allocator<int> > >’ has no member named ‘pop’
prog.cpp:25: warning: unused variable ‘v’

Я думал, что это было то, для чего :: value_type был?

Ответы [ 2 ]

23 голосов
/ 10 ноября 2011

Вы должны использовать typename:

typename T::value_type pop()

и т. Д.

Причина в том, что компилятор не может знать, является ли T :: value_type типом переменной-члена (никто не мешает вам определить тип struct X { int value_type; }; и передать его в шаблон). Однако без этой функции код не может быть проанализирован (поскольку значение конструкций изменяется в зависимости от того, обозначает ли какой-либо идентификатор тип или переменную, например, T * p может быть умножением или объявлением указателя). Следовательно, правило состоит в том, что все, что может быть типом или переменной и явно не помечено как тип с префиксом typename, считается переменной.

7 голосов
/ 10 ноября 2011

Используйте ключевое слово typename, чтобы указать, что это действительно тип.

void push(typename T::value_type& item)

typename T::value_type pop()
...