我想构建一个Stack
类,以便用户能够选择他想用于实现的容器Stack
.例如,List/Vector
.
部分代码:
stack.h
#ifndef STACK_H_
#define STACK_H_
template <typename T, template<typename T> class ContainerType>
class Stack{
ContainerType<T> container;
public:
Stack() : container(ContainerType<T>()){}
};
#endif /* STACK_H_ */
Run Code Online (Sandbox Code Playgroud)
TEST.CPP
#include "stack.h"
#include <vector>
int main(){
Stack<int, std::vector<int> > stack;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
好吧,它没有编译.我在网上得到了下一个错误:
Stack<int, std::vector<int> > stack;
Run Code Online (Sandbox Code Playgroud)
错误:
expected a class template, got `std::vector<int, std::allocator<int> >' test.cpp
invalid type in declaration before ';' token test.cpp
type/value mismatch at argument 2 in template parameter
list for `template<class T, template<class T> class ContainerType>
class Stack' test.cpp
?
Run Code Online (Sandbox Code Playgroud)
Xeo*_*Xeo 22
首先,它将是std::vector
,而不是别的,因为vector
驻留在std
命名空间中,你要求的是模板模板参数,而std::vector<int>
不再是模板.接下来,std::vector
实际上需要两个模板参数,一个用于类型,另一个用于分配器:
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;
Run Code Online (Sandbox Code Playgroud)
现在,这只启用具有两个模板参数的容器作为基础类型,因此您最好使用标准做的事情:将其作为普通类型:
template <typename T, typename ContainerType>
class Stack{
ContainerType container;
// ...
};
// usage:
Stack<int, std::vector<int> > s;
Run Code Online (Sandbox Code Playgroud)
要确保底层类型具有相同的T
,您可以执行虚假的"静态断言",或者如果您启用了C++ 0x编译器,则可以执行实际的静态断言:
#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;
// ...
};
Run Code Online (Sandbox Code Playgroud)
这样做是因为,如果T
是从所使用的容器的不同T
,这将是一个typedef char ERROR_different_vale_type[-1]
,和负大小的阵列不可能存在,这会导致编译错误.:)现在,使用C++ 0x你可以static_assert
这样:
#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;
// ...
};
Run Code Online (Sandbox Code Playgroud)
为方便起见,您现在可以为常见情况指定默认模板参数:
template <typename T, typename ContainerType = std::vector<T>>
class Stack{
ContainerType container;
// ...
};
// usage:
Stack<int> s;
Run Code Online (Sandbox Code Playgroud)
在这一点上,您可以使用std::stack
哪个正是这样做(尽管它std::deque
用作底层类型).:)
归档时间: |
|
查看次数: |
11972 次 |
最近记录: |