#include <cassert>
#include <vector>
using namespace std;
template<typename Type, int Dimension>
const vector<Type> make_fixed_vector(const Type& value = Type())
{
return vector<Type>(Dimension, value);
}
int main(void)
{
vector<int> v3 = make_fixed_vector<int, 3>();
assert(v3.size() == 3);
}
C++1x 编译器能够推断出变量的类型,这在使用这种技术声明多维“固定”向量时非常方便:
.
.
.
template<typename Type, int Rows, int Columns>
const vector<vector<Type> > make_fixed_vector_vector(const Type& value = Type())
{
return vector<vector<Type> >(Rows, make_fixed_vector<Type, Columns>(value));
}
int main(void)
{
auto vv = make_fixed_vector_vector<int, 3, 4>(42);
assert(vv.size() == 3);
assert(vv[0].size() == 4);
assert(vv[0][0] == 42);
assert(vv[2][3] == 42);
}
在为列表表达式编写解析器函数时,我有这个简单的想法,该函数将返回一个固定大小的整数向量向量。例如,vector<vector<int> >(1) 用于“(0,8)”之类的表达式,而vector<vector<int> >(2) 用于“(3-4)(5)”之类的表达式等等。在应用程序中,最多可以有 5 个带括号的定义,它们表示对程序数据的逻辑引用。我首先尝试解析vector<vector<int> >(5)。工作了吗?好的,得到了参考类型A,最详细的一个。否则vector<vector<int> >(4) 表示引用类型 B 等。
为此,make_fixed_vector 运行良好,但从一般角度来看,该技术存在缺陷。最值得注意的是,由于make_fixed_vector 不返回真实类型,因此无法在编译时检查其维度。在运行时reserve、resize 和push_back 调用是可能的。而且,由于函数模板不能有默认模板参数,自定义分配器需要更多的输入:
template<typename Type, int Dimension, template<typename> class Allocator>
const vector<Type Allocator<Type> > make_fixed_vector(const Type& value = Type())
{
return vector<Type, Allocator<Type> >(Dimension, value);
}
vector<int> v3 = make_fixed_vector<int, 3, std::allocator>();
等等。等等。但是这种技术使较小的项目保持基本。除非这种美德是相关的,否则 Boost 的 boost::array 可能更现实。