cfc::array
boost提供了boost::array,但是那只是一维的数组,我实现的这个支持一维,二维和三
维数组,三维以上的没有支持,我想你大概也不大会用到吧?:)
用标准STL容器vector来实现多维数组的话,空间是不连续的,用boost::array实现多维
数组的话,空间是连续的,但是boost的array没有基接口.
我提供的数组类同时支持我实现的这个支持一维,二维和三维数组,提供了所有数组的
基类array_base,一维数组的基类array_1d_base,二维数组的基类array_2d_base,三维数
组的基类array_3d_base,这就解决了C中多维数组的参数传递麻烦的问题.
该模板类实现了STL接口,可以像使用STL容器一样使用它.由于我对STL了解不过,实现的
也许不好,欢迎不吝斧正
同时实现了[]和()运算符,实现()运算符的原因是它再多为数组的情况下比[]要高效的
多.使用()的原因是受Basic语言的影响
对于每一维数组本身和基类的,我都提供了不同版本的实现,例如在基类array_2d_base
中,我用乘法实现(),而在array_2d中,我用原始数组的[]来实现,
这好像违背了不覆盖基类非虚函数的原则,其实不然,因为派生类中的重载做的是和基
类中完全一样的动作,但是却是优化的版本,而且基类的版本不算很低效,没必要用虚
函数,因为这样可能更慢而且不利于内联化.这样做的唯一原因就是为了效率.
还需要注意的是,由于MSVC模板实现的不好,有些特性还不适用,例如VC把模板中的数组
引用的定义视为错误,因为它把数组的大小看作0,而指针就没事,暂时还没解决
我还写了一个 dynamic_array<typename T,int dim=1>类,根据dim分别派生于
array_1d_base,array_2d_base,array_3d_base还没调试好,等好了,而且本文没有受
到大家唾弃的话在post吧.还有share_array...任重而道远,以后再说吧.
所有的类定义于namespace cfc,meams chen feng's class libraries.
你会在我的源代码中看到boost::function和boost::array的影子,感谢boost!
模板类的使用很简单:
#include "cfc\array.h"
using namespace cfc;
void foo(array_1d_base<int> & a)
{
a[0]+=10;
}
int main()
{
array<int ,10> a1;//一维数组
array<int ,10, 10> a2;//二维数组
array<int ,10, 10, 10> a3;//二维数组
a1[0]=10;
a1(0)=10; //Basic风格
a3[0](1,1)=10;
a3[0][0](0)=10;
foo(a1);
foo(a2[0]);
foo(a3[0][0]);
}
这是源程序:
使用了根据模板参数选择基类从而可以实例化生成有较大差别的类的手法, :)
////////////////////////////////////////////////////////////////////////////
////////////////////////////////
file://array.h ,array类和其的实现
#ifndef _ARRAY_H_
#define _ARRAY_H_
#ifdef _MSC_VER
#define CFC_STATIC_CONST(type, assign) enum{assign}
#else
#define static const type assign
#endif
#include "arrays.h"
namespace cfc
{
namespace detail
{
namespace array
{
template <int n>
struct real_get_impl
{
};
template <>
struct real_get_impl<1>
{
template<typename T, int d1, int d2, int d3>
struct dimensions
{
typedef array_1d<T, d1> type;
};
};
template <>
struct real_get_impl<2>
{
template <typename T, int d1, int d2, int d3
>
struct dimensions
{
typedef array_2d<T, d1, d2> type;
};
};
template <>
struct real_get_impl<3>
{
template <typename T, int d1, int d2, int d3
>
struct dimensions
{
typedef array_3d<T, d1, d2, d3> type
;
};
};
template <typename T, int d1, int d2, int d3>
struct get_impl
{
CFC_STATIC_CONST(int, value = int(d2!=-1)
+
int(d3!=-1)
+
1
);
typedef typename real_get_impl<value>::
template dimensions<T, d1, d2, d3>::
type type;
};
}
}
template <typename T, int d1, int d2 = -1, int d3 = -1>
class array : public detail::array::get_impl<T, d1, d2, d3>::type
{
typedef typename detail::array::
get_impl<T, d1, d2, d3>::type
base_type;
public:
array(){}
};
}
#endif file://_ARRAY_H_
////////////////////////////////////////////////////////////
// array_base.h
#ifndef _ARRAY_BASE_H_
#define _ARRAY_BASE_H_
#include <cstddef>
#include <iterator>
#include <algorithm>
#include <stdexcept>
namespace cfc
{
template <typename T>
class array_base
{
public:
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef T& reference;
typedef const T& const_reference;
typedef /*std*/::size_t size_type;
typedef /*std*/::ptrdiff_t difference_type;
#ifdef _MSC_VER
typedef std::reverse_iterator<iterator,T> reverse_iterator;
typedef std::reverse_iterator<const_iterator,T> const_reverse_iterat
or;