#include <iostream>
#include <vector>
#include <deque>
#include <ext/pool_allocator.h>
using namespace std;
#if 1
// CASE1:不使用模版模版参数,明确指定容器的类型,比如STL库的stack实现,见下:
template <typename T,
typename CONT = std::deque<T>>
class Stack1 {
private:
CONT elems; // elements
public:
void push(T const&); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const { // return whether the stack is empty
return elems.empty();
}
};
int main(int argc, char const *argv[])
{
Stack1<int, vector<int>> s;
cout << boolalpha <<s.empty() << endl;
return 0;
}
#elif 0
// CASE2:使用alias template的语法(c++11)传参
// 推导过程:其实E只是占位符号,会替换alias template(即using语法)中声明的原型。此处可以省略E,使用前面已出现的T。(具体参见case3)
template <typename T,
template <typename E> class CONT = std::deque>
class Stack2
{
private:
CONT<T> elems; // elements
public:
void push(T const &); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const
{ // return whether the stack is empty
return elems.empty();
}
};
template <class E>
using Vec = vector<E, allocator<E>>;
int main(int argc, char const *argv[])
{
Stack2<int, Vec> s;
cout << boolalpha << s.empty() << endl;
return 0;
}
#elif 0
// CASE3:省略E,使用之前出现过的T去做推导
template <typename T,
template <typename> class CONT = std::deque>
class Stack3
{
private:
CONT<T> elems; // elements
public:
void push(T const &); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const
{ // return whether the stack is empty
return elems.empty();
}
};
template <class E>
using Vec = vector<E, allocator<E> >;
int main(int argc, char const *argv[])
{
cout << "case 3" << endl;
Stack3<int, Vec> s;
cout << boolalpha << s.empty() << endl;
return 0;
}
#elif 0
// CASE4
// 同理,可以不写using语法,直接在模板类中写全,此方法适用于c++98(但是需要注意两个>>在一起的时候需要加空格,不然报错)
template <typename T,
template <typename E, typename Alloc = allocator<E> > class CONT>
class Stack4
{
private:
CONT<T, __gnu_cxx::__pool_alloc<T>> elems; // 基于内存池的分配器
public:
void push(T const &); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const
{ // return whether the stack is empty
return elems.empty();
}
};
int main(int argc, char const *argv[])
{
cout << "case 4" << endl;
Stack4<int, vector> s;
cout << boolalpha << s.empty() << endl;
return 0;
}
#elif 0
// CASE5:省略占位符E,使用之前出现过的T
// 也可以省略一个占位符号E,注意:如果有默认=出现的地方不能省略类型别名,比如“typename Alloc = allocator<T>”中的T
// 要省略T就得替换为前置出现的别名(因为省略类型之后变为了模板类),
// 比如“typename Alloc = allocator<T>”变为“template<typename M> class Alloc = alloctor”,详见case6
template <typename T,
template <typename, typename Alloc = allocator<T>> class CONT>
class Stack5
{
private:
CONT<T> elems; // elements
public:
void push(T const &); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const
{ // return whether the stack is empty
return elems.empty();
}
};
int main(int argc, char const *argv[])
{
cout << "case 5" << endl;
Stack5<int, vector> s;
cout << boolalpha << s.empty() << endl;
return 0;
}
#elif 0
// CASE6:同理,可以省略M,使用之前的T,如case7
// CASE6\CASE7 可以通过编译,但无测试用例,太复杂。
template <typename T,
template <typename, template <typename M> class Alloc = allocator> class CONT>
class Stack6
{
private:
CONT<T> elems; // elements
public:
void push(T const &); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const
{ // return whether the stack is empty
return elems.empty();
}
};
int main(int argc, char const *argv[])
{
//cout << "case 6" << endl;
// 太复杂,不建议使用,无测试成功的用例
return 0;
}
#elif 0
// CASE7:同理,可以省略M,使用之前的T,如case7
//
template <typename T,
template <typename, template <typename> class Alloc = allocator> class CONT>
class Stack7
{
private:
CONT<T> elems; // elements
public:
void push(T const &); // push element
void pop(); // pop element
T top() const; // return top element
bool empty() const
{ // return whether the stack is empty
return elems.empty();
}
};
int main(int argc, char const *argv[])
{
// 太复杂,不建议使用,无测试成功的用例
return 0;
}
#endif
备份地址: 【玩转c++模板模板参数】