#c #templates
#c #шаблоны
Вопрос:
Я пытаюсь скомпилировать следующий пример кода из «C Templates — The Complete Guide» Дэвида Вандевурда и Николая М. Джосуттиса:
#include <iostream>
#include <deque>
#include <vector>
#include <stdexcept>
#include <memory>
template < typename T,
template < typename ELEM, typename = std::allocator< ELEM > >
class CONT = std::deque >
class ourstack
{
private:
CONT< T > elems;
public:
void push( T constamp; );
void pop();
T top() const;
bool empty() const
{ return elems.empty(); }
template < typename T2 >
template < typename ELEM2,
typename = std::allocator< ELEM2 > > class CONT2 >
ourstack< T, CONT >amp; operator = ( ourstack< T2, CONT2 > const amp; );
};
template < typename T,
template < typename, typename > class CONT >
void ourstack< T, CONT>::push( T constamp; elem )
{
elems.push_back( elem );
}
template < typename T,
template < typename, typename > class CONT >
void ourstack< T, CONT>::pop()
{
if ( elems.empty() )
{
throw std::out_of_range( "Stack empty" );
}
elems.pop_back();
}
template < typename T,
template < typename, typename > class CONT >
void ourstack< T, CONT>::top() const
{
if ( elems.empty() )
{
throw std::out_of_range( "Stack empty" );
}
return elems.back();
}
template < typename T,
template < typename, typename > class CONT >
template < typename T2 >
template < typename, typename > class CONT2 >
ourstack< T, CONT >amp; ourstack< T, CONT >::operator = ( ourstack< T2, CONT2 > const amp; op2 )
{
if (( void*) this == (void*) op2 )
{
return *this;
}
ourstack< T2 > tmp( op2 );
elems.clear();
while ( !tmp.empty() )
{
elems.push_front( tmp.top() );
tmp.pop();
}
return *this;
}
int main( int argc, char* argv[] )
{
ourstack< int > s;
return 0;
}
Но
Я использую gcc версии 4.4.3.
Компилятор пишет сообщения:
g -Wall template_of_template.cpp -o template_of_template
template_of_template.cpp:22: error: too many template-parameter-lists
template_of_template.cpp:22: error: expected unqualified-id before ‘>’ token
template_of_template.cpp:46: error: prototype for ‘void ourstack<T, CONT>::top() const’ does not match any in class ‘ourstack<T, CONT>’
template_of_template.cpp:17: error: candidate is: T ourstack<T, CONT>::top() const
template_of_template.cpp:58: error: too many template-parameter-lists
template_of_template.cpp:58: error: expected unqualified-id before ‘>’ token
В чем проблема?
Комментарии:
1. Вы используете оба
outstack
иourstack
…
Ответ №1:
Единственная проблема с кодом заключается в том, что вам нужно научиться печатать более точно. ;-]
После исправления нескольких опечаток ( t
вместо r
, >
вместо ,
), вот тот же код в компилируемом состоянии:
#include <iostream>
#include <deque>
#include <vector>
#include <stdexcept>
#include <memory>
template < typename T,
template < typename ELEM,
typename = std::allocator< ELEM > > class CONT = std::deque >
class ourstack
{
private:
CONT< T > elems;
public:
void push( T constamp; );
void pop();
T top() const;
bool empty() const
{ return elems.empty(); }
template < typename T2,
template < typename ELEM2,
typename = std::allocator< ELEM2 > > class CONT2 >
ourstack< T, CONT >amp; operator = ( ourstack< T2, CONT2 > const amp; );
};
template < typename T,
template < typename, typename > class CONT >
void ourstack< T, CONT>::push( T constamp; elem )
{
elems.push_back( elem );
}
template < typename T,
template < typename, typename > class CONT >
void ourstack< T, CONT>::pop()
{
if ( elems.empty() )
{
throw std::out_of_range( "Stack empty" );
}
elems.pop_back();
}
template < typename T,
template < typename, typename > class CONT >
T ourstack< T, CONT>::top() const
{
if ( elems.empty() )
{
throw std::out_of_range( "Stack empty" );
}
return elems.back();
}
template < typename T,
template < typename, typename > class CONT >
template < typename T2,
template < typename, typename > class CONT2 >
ourstack< T, CONT >amp; ourstack< T, CONT >::operator = ( ourstack< T2, CONT2 > const amp; op2 )
{
if (( void*) this == (void*) op2 )
{
return *this;
}
ourstack< T2 > tmp( op2 );
elems.clear();
while ( !tmp.empty() )
{
elems.push_front( tmp.top() );
tmp.pop();
}
return *this;
}
int main( int argc, char* argv[] )
{
ourstack< int > s;
return 0;
}
Ответ №2:
template < typename T2 >
template < typename ELEM2,
typename = std::allocator< ELEM2 > > class CONT2 >
ourstack< T, CONT >amp; operator = ( ourstack< T2, CONT2 > const amp; );
Там есть два template
объявления, где должно быть только одно. Я не уверен, но я думаю, что вы хотите этого:
template <
typename T2
, template < typename ELEM2, typename = std::allocator< ELEM2 > > class CONT2
>
ourstack< T, CONT >amp; operator = ( ourstack< T2, CONT2 > const amp; );
Также обратите внимание, что нет смысла указывать имена для параметров шаблона шаблона.