2012-03-09 2 views
1

на примере на pp. 179Определить и вывести параметр из параметра шаблона Шаблон

template<template<typename T, typename A> class C, typename T, typename A> 
                ^^^^^^^^^^^^^^^^^^^^^^ 
void erase(C<T, A>&c, const T& item) 
{ 
    c.erase(std::remove(c.begin(), c.end(), item), c.end()); 
} 

int _tmain(int /*argc*/, _TCHAR* /*argv*/[]) 
{ 
    list<int> lst; 
    lst.push_back(42); 
    erase(lst, 42); 
} 

Если удалить typename T, typename A из erase функции подписи, VS2010 компилятор дает следующие ошибки:

Error 1 error C2065: 'T' : undeclared identifier 
Error 2 error C2065: 'A' : undeclared identifier 
Error 3 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
Error 4 error C2143: syntax error : missing ',' before '&' 

Вопрос1> В чем причина поведения ind эти ошибки компиляции.

Верно ли, что мы всегда должны явно определять параметры типа, используемые в параметре шаблона шаблона?

Question2> Когда мы вызываем следующую строку, как компилятор выводит тип A?

erase(lst, 42) 

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

См list

template < class T, class Allocator = allocator<T> > class list; 

И тип A является allocator<T>?

ответ

8

Вопрос 1

Первый T и A являются параметрами для C, а не к вашему erase() шаблона. Поэтому они не видны ему, то, что видно, это второй и третий параметры, которые вы выделяете с помощью ^^^. Обратите внимание, что первым параметром является не a typename/class, это шаблон класса. Сам шаблон класса не является типом, только его экземпляры.

Чтобы лучше понять, как первый T и A не видны и на самом деле не играют никакой роли, вы можете переписать так:

template<template<typename, typename> class C, typename T, typename A> 

Вопрос 2

может вывести A, потому что lst прошел как C<T, A>, поэтому A является вторым параметром шаблона класса типа lst.

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

template <typename C> 
void erase(C& c, const typename C::value_type& item) 
{ 
    c.erase(std::remove(c.begin(), c.end(), item), c.end()); 
} 

Таким образом, вы не ограничиваете количество и значение C параметров шаблона. Фактически, здесь C может быть не шаблонным, если требуется.

+0

+1 отличный ответ на вопрос и предоставляет решение. –

1

Если вы их удалите, A и T известны только в контексте C, а не в контексте вашего шаблона erase().

Смежные вопросы