Pierwszy byłoby std::vector
i nic więcej, bo vector
rezyduje w przestrzeni nazw std
i prosicie o szablonu szablonu parametr, natomiast std::vector<int>
nie jest już szablon. Następnie std::vector
faktycznie ma dwa parametrów szablonu, jeden dla danego typu, a inne dla podzielnika:
template <
typename T,
template<typename, typename> class ContainerType,
typename Alloc = std::allocator<T>
>
class Stack{
ContainerType<T, Alloc> container;
// ...
};
// usage:
Stack<int, std::vector> s;
Teraz ta umożliwia jedynie pojemniki z dwoma parametrami szablonu takiego typu bazowego, tak jesteś lepszy off z tym, co standardowy sposób: wziąć go jako normalnego typu:
template <typename T, typename ContainerType>
class Stack{
ContainerType container;
// ...
};
// usage:
Stack<int, std::vector<int> > s;
Aby upewnić się, że typ bazowy ma taką samą T
można zrobić fake „statyczny assert”, lub jeśli masz C++ 0x włączony kompilator, możesz zrobić faktyczny statyczny assert:
#include <tr1/type_traits> // C++03 us std::tr1::is_same
//#include <type_traits> // C++0x, use std::is_same
template <typename T, typename ContainerType>
class Stack{
typedef typename ContainerType::value_type underlying_value_type;
typedef char ERROR_different_value_type[
std::tr1::is_same<T, underlying_value_type>::value ? 1 : -1
]
ContainerType container;
// ...
};
To działa, ponieważ jeśli T
różni się od używanych kontenera T
, będzie to typedef char ERROR_different_vale_type[-1]
i tablicą z negatywnej wielkości nie mogą ewentualnie występować, co powoduje błąd kompilatora. :) Teraz, z C++ 0x można po prostu static_assert
że:
#include <tr1/type_traits> // C++03
//#include <type_traits> // C++0x
template <typename T, typename ContainerType>
class Stack{
typedef typename ContainerType::value_type underlying_value_type;
static_assert(std::tr1::is_same<T, underlying_value_type>::value,
"Error: The type of the stack must be the same as the type of the container");
ContainerType container;
// ...
};
Dla wygody, można teraz określić argument domyślny szablon dla wspólnej sprawy:
template <typename T, typename ContainerType = std::vector<T>>
class Stack{
ContainerType container;
// ...
};
// usage:
Stack<int> s;
I w tym momencie może po prostu użyć std::stack
, który robi dokładnie to (chociaż używa std::deque
jako typ bazowy).:)
wektor jest w std namespace – nullpotent
Ten błąd jest konsekwencją kulawej praktyki polegającej na tym, że zawsze piszę 'using namespace std;' i przyzwyczajam się do niego. –
@Armen Ale prawdziwy błąd jest gdzie indziej. –