打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
C++ Template 表达式模板

C++ Template 表达式模板

//exprtmpl/sarray1.hpp
#include <stddef.h>
#include <cassert>


template<typename T>
class SArray
{
public:
 
   //create array with initial size
    explicitSArray (size_t s)
            :storage(new T[s]), storage_size(s)
    {
        init();
    }


    //copy constructor
    SArray(SArray<T> const&orig)
            :storage(new T[orig.size()]), storage_size(orig.size())
    {
        copy(orig);
    }


    //destructor: free memory
    ~SArray()
    {
        delete[]storage;
    }


    //assignment operator
    SArray<T>&operator= (SArray<T>const& orig)
    {
        if(&orig!=this)
        {
            copy(orig);
        }
        return*this;
    }


    //return size
    size_tsize() const
    {
        returnstorage_size;
    }


    //index operator for constants and variables
    Toperator[] (size_t idx) const
    {
        returnstorage[idx];
    }
    T&operator[] (size_t idx)
    {
        returnstorage[idx];
    }


protected:
    //init values with default constructor
    voidinit()
    {
        for(size_t idx = 0; idx<size(); ++idx)
        {
            storage[idx]= T();
        }
    }
    //copy values of another array
    voidcopy (SArray<T>const& orig)
    {
        assert(size()==orig.size());
        for(size_t idx = 0; idx<size(); ++idx)
        {
            storage[idx]= orig.storage[idx];
        }
    }


private:
    T*    storage;      // storage of the elements
    size_tstorage_size;  // number ofelements
};


// exprtmpl/sarrayops1.hpp
template<typename T>
SArray<T> operator+(SArray<T> const& a,SArray<T> const&b)
{
    SArray<T>result(a.size());
    for(size_t k = 0; k<a.size(); ++k)
    {
        result[k]= a[k]+b[k];
    }
    returnresult;
}


// multiplication of two SArrays
template<typename T>
SArray<T> operator*(SArray<T> const& a,SArray<T> const&b)
{
    SArray<T>result(a.size());
    for(size_t k = 0; k<a.size(); ++k)
    {
        result[k]= a[k]*b[k];
    }
    returnresult;
}


// multiplication of scalar and SArray
template<typename T>
SArray<T> operator* (Tconst& s, SArray<T>const& a)
{
    SArray<T>result(a.size());
    for(size_t k = 0; k<a.size(); ++k)
    {
        result[k]= s*a[k];
    }
    returnresult;
}


// multiplication of SArray and scalar
// addition of scalar and SArray
// addition of SArray and scalar
//...




//exprtmpl/sarrayops2.hpp
#include<stddef.h>
#include<cassert>

template<typenameT>
class SArray
{
public:
// create array with initial size
explicit SArray (size_t s)
: storage(new T[s]), storage_size(s)
{
init();
}

// copy constructor
SArray (SArray<T>const& orig)
: storage(new T[orig.size()]), storage_size(orig.size())
{
copy(orig);
}

// destructor: free memory
~SArray()
{
delete[] storage;
}

// assignment operator
SArray<T>& operator=(SArray<T> const&orig)
{
if (&orig!=this)
{
copy(orig);
}
return *this;
}

// return size
size_t size() const
{
return storage_size;
}

// index operator for constants and variables
T operator[] (size_t idx) const
{
return storage[idx];
}
T& operator[] (size_t idx)
{
return storage[idx];
}

protected:
// init values with default constructor
void init()
{
for (size_t idx = 0; idx<size(); ++idx)
{
storage[idx] = T();
}
}
// copy values of another array
void copy (SArray<T>const& orig)
{
assert(size()==orig.size());
for (size_t idx = 0; idx<size(); ++idx)
{
storage[idx] = orig.storage[idx];
}
}

private:
T*storage;// storage of the elements
size_t storage_size;// number ofelements

public:
SArray<T>& operator+=(SArray<T>const&b);
SArray<T>&operator*=(SArray<T>const& b);
SArray<T>& operator*=(Tconst& s);
};

//exprtmpl/sarrayops2.hpp
template<classT>
SArray<T>&SArray<T>::operator+=(SArray<T> const&b)
{
for (size_t k = 0; k<size(); ++k)
{
(*this)[k] += b[k];
}
return *this;
}

// multiplicative assignment ofSArray
template<classT>
SArray<T>&SArray<T>::operator*=(SArray<T> const&b)
{
for (size_t k = 0; k<size(); ++k)
{
(*this)[k] *= b[k];
}
return *this;
}

// multiplicative assignment ofscalar
template<classT>
SArray<T>&SArray<T>::operator*=(T const& s)
{
for (size_t k = 0; k<size(); ++k)
{
(*this)[k] *= s;
}
return *this;
}






//exprtmpl/exprops1.hpp
#include<stddef.h>
#include<cassert>

// includehelper class traitstemplate to select whether to refer toan
// ``expression_rtemplate node''either ``by value'' or ``byreference.''
#include"exprops1a.hpp"

// class forobjects thatrepresent the addition of twooperands
template<typename T, typenameOP1, typenameOP2>
classA_Add
{
private:
typename A_Traits<OP1>::ExprRefop1;//first operand
typename A_Traits<OP2>::ExprRefop2;//second operand

public:
// constructor initializes references tooperands
A_Add (OP1 const& a, OP2 const&b)
: op1(a), op2(b)
{}

// compute sum when value requested
T operator[] (size_t idx) const
{
return op1[idx] + op2[idx];
}

// size is maximum size
size_t size() const
{
assert (op1.size()==0 || op2.size()==0
|| op1.size()==op2.size());
return op1.size()!=0 ? op1.size() :op2.size();
}
};

// class forobjects thatrepresent the multiplication of twooperands
template<typename T, typenameOP1, typenameOP2>
classA_Mult
{
private:
typename A_Traits<OP1>::ExprRefop1;//first operand
typename A_Traits<OP2>::ExprRefop2;//second operand

public:
// constructor initializes references tooperands
A_Mult (OP1 const& a, OP2 const&b)
: op1(a), op2(b)
{}

// compute product when value requested
T operator[] (size_t idx) const
{
return op1[idx] * op2[idx];
}

// size is maximum size
size_t size() const
{
assert (op1.size()==0 || op2.size()==0
|| op1.size()==op2.size());
return op1.size()!=0 ? op1.size() :op2.size();
}
};


//exprtmpl/exprscalar.hpp
template <typenameT>
class A_Scalar
{
private:
Tconst& s;// value of the scalar

public:
// constructor initializes value
A_Scalar (T const& v)
: s(v)
{}

// for index operations the scalar is the value of eachelement
T operator[] (size_t) const
{
return s;
}

// scalars have zero as size
size_t size() const
{
return 0;
};
};

//exprtmpl/exprops1a.hpp
template <typenameT>
classA_Scalar;

// primarytemplate
template <typenameT>
class A_Traits
{
public:
typedefT const& ExprRef;// type torefer to isconstant reference
};

// partial specialization forscalars
template <typenameT>
classA_Traits<A_Scalar<T>>
{
public:
typedef A_Scalar<T> ExprRef;// typeto refer to is ordinary value
};

//exprtmpl/exprarray.hpp
#include<stddef.h>
#include<cassert>
#include"sarray1.hpp"

template <typenameT, typename Rep =SArray<T>>
class Array
{
private:
Rep expr_rep;// (access to) thedata of the array

public:
// create array with initial size
explicit Array (size_t s)
: expr_rep(s)
{}

// create array from possible representation
Array (Rep const& rb)
: expr_rep(rb)
{}

// assignment operator for same type
Array& operator= (Array const&b)
{
assert(size()==b.size());
for (size_t idx = 0; idx<b.size(); ++idx)
{
expr_rep[idx] = b[idx];
}
return *this;
}

// assignment operator for arrays of different type
template<typename T2, typenameRep2>
Array& operator= (Array<T2,Rep2> const& b)
{
assert(size()==b.size());
for (size_t idx = 0; idx<b.size(); ++idx)
{
expr_rep[idx] = b[idx];
}
return *this;
}

// size is size of represented data
size_t size() const
{
return expr_rep.size();
}

// index operator for constants and variables
Toperator[] (size_t idx) const
{
assert(idx<size());
return expr_rep[idx];
}
T& operator[] (size_t idx)
{
assert(idx<size());
return expr_rep[idx];
}

// return what the array currently represents
Rep const& rep() const
{
return expr_rep;
}
Rep& rep()
{
return expr_rep;
}
};

//exprtmpl/exprops2.hpp
template <typenameT, typename R1,typename R2>
Array<T,A_Add<T,R1,R2>>
operator+(Array<T,R1> const&a,Array<T,R2> const&b)
{
returnArray<T,A_Add<T,R1,R2>>
(A_Add<T,R1,R2>(a.rep(),b.rep()));
}

// multiplication of twoArrays
template <typenameT, typename R1,typename R2>
Array<T,A_Mult<T,R1,R2>>
operator*(Array<T,R1> const&a,Array<T,R2> const&b)
{
returnArray<T,A_Mult<T,R1,R2>>
(A_Mult<T,R1,R2>(a.rep(),b.rep()));
}

// multiplication of scalar andArray
template <typenameT, typename R2>
Array<T,A_Mult<T,A_Scalar<T>,R2>>
operator* (Tconst& s,Array<T,R2>const& b)
{
returnArray<T,A_Mult<T,A_Scalar<T>,R2>>
(A_Mult<T,A_Scalar<T>,R2>(A_Scalar<T>(s),b.rep()));
}

// multiplication of Array andscalar
// addition of scalar andArray
// addition of Array andscalar

//exprtmpl/exprops3.hpp
template<typenameT, typename A1,typename A2>
classA_Subscript
{
public:
// constructor initializes references to operands
A_Subscript (A1 const& a, A2 const&b)
: a1(a), a2(b)
{}

// process subscription when value requested
Toperator[] (size_t idx) const
{
return a1[a2[idx]];
}
T& operator[] (size_t idx)
{
return a1[a2[idx]];
}

// size is size of inner array
size_t size() const
{
return a2.size();
}
private:
A1 const& a1;// referenceto first operand
A2 const& a2;// referenceto second operand
};

//exprtmpl/exprops4.hpp
template<typenameT, typename R>
template<typenameT2, typename R2>
inline
Array<T,A_Subscript<T, R,R2>>
Array<T,R>::operator[](Array<T2,R2>const& b)
{
return Array<T, A_Subscript<T, R,R2> >
(A_Subscript<T, R, R2>(*this,b));
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C 技巧:二维动态数组类模板
c++11模板的特化
在你的游戏中应用LUA
stl_alloc.h
C++函数模板详解
Vector类模板界面及其函数的实现
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服