C++安全方便高效地复制对象数组

在C++中,我们经常遇到需要对一个对象数组进行复制,比如下面一个结构:

struct STest
{
    int a;
    int b;
    vector<int> vctInt;
};

我们定义了两个数组:

STest A[20];
STest B[20];

需要将数组A中的所有内容复制到B数组中,通常我们的做法都是这样:

for(size_t i = 0; i < ARRAYSIZE(A); ++i)
{
    A[i] = B[i];
}
这里不能直接使用memcpy,因为STest中有vector类型。但是,如果我们定义的是内置类型的数组,则上面的代码效率较低,而直接使用memcpy会更高效。

为了解决上面的问题,我们可以使用C++模板对不同的类型进行不同的处理。下面有两种写法:

第一种写法是最容易想到的,就是直接写一个模板,并对这个模板的C++内置类型进行特化处理:

template<typename T,size_t N>
inline void ArrayAssign(T (&A)[N], T (&B)[N])
{
    for(size_t i = 0; i < N; ++i)
        A[i] = B[i];
}

template<size_t N>
inline void ArrayAssign(bool (&A)[N], bool (&B)[N])
{
    memcpy(A,B,sizeof(A));
}

template<size_t N>
inline void ArrayAssign(char (&A)[N], char (&B)[N])
{
    memcpy(A,B,sizeof(A));
}

template<size_t N>
inline void ArrayAssign(short (&A)[N], short (&B)[N])
{
    memcpy(A,B,sizeof(A));
}

template<size_t N>
inline void ArrayAssign(int (&A)[N], int (&B)[N])
{
    memcpy(A,B,sizeof(A));
}

template<size_t N>
inline void ArrayAssign(long long (&A)[N], long long (&B)[N])
{
    memcpy(A,B,sizeof(A));
}

template<size_t N>
inline void ArrayAssign(unsigned char (&A)[N], unsigned char (&B)[N])
{
    memcpy(A,B,sizeof(A));
}

template<size_t N>
inline void ArrayAssign(unsigned short (&A)[N], unsigned short (&B)[N])
{
    memcpy(A,B,sizeof(A));
}

template<size_t N>
inline void ArrayAssign(unsigned int (&A)[N], unsigned int (&B)[N])
{
    memcpy(A,B,sizeof(A));
}

template<size_t N>
inline void ArrayAssign(unsigned long long (&A)[N],unsigned long long (&B)[N])
{
    memcpy(A,B,sizeof(A));
}

下面是第二种写法,这种写法,把内置类型的判断提出来,可以方便其它地方使用:

template<bool A,typename B,typename C>
struct _if{};

template<typename B,typename C>
struct _if<true,B,C>{ typedef B Type; };

template<typename B,typename C>
struct _if<false,B,C>{ typedef C Type; };

template<typename T,size_t N>
inline size_t ARRAYSIZE(T (&)[N])
{
    return N;
}

template<typename T>
struct IsInnerType { static const bool Value = false; };

template<>
struct IsInnerType<bool> { static const bool Value = true; };
template<>
struct IsInnerType<char> { static const bool Value = true; };
template<>
struct IsInnerType<short> { static const bool Value = true; };
template<>
struct IsInnerType<int> { static const bool Value = true; };
template<>
struct IsInnerType<long long> { static const bool Value = true; };
template<>
struct IsInnerType<unsigned char> { static const bool Value = true; };
template<>
struct IsInnerType<unsigned short> { static const bool Value = true; };
template<>
struct IsInnerType<unsigned int> { static const bool Value = true; };
template<>
struct IsInnerType<unsigned long long> { static const bool Value = true; };

template<typename T,size_t N>
struct ArrayAssignInnerType
{
    static inline void Invoke(T (&A)[N], T (&B)[N])
    {
        memcpy(A,B,sizeof(A));
    }
};

template<typename T,size_t N>
struct ArrayAssignCustomType
{
    static inline void Invoke(T (&A)[N], T (&B)[N])
    {
        for(size_t i = 0; i < N; ++i)
            A[i] = B[i];
    }
};

template<typename T,size_t N>
inline void ArrayAssign(T (&A)[N], T (&B)[N])
{
    _if<IsInnerType<T>::Value,ArrayAssignInnerType<T,N>,ArrayAssignCustomType<T,N> >::Type::Invoke(A,B);
}

经过上面的处理,我们可以不用担心效率问题;同时,写起来也方便很多,而且不会出错。直接按如下写就OK了:

ArrayAssign(B,A);
以上代码在VC和GCC下编译通过。


转载于:https://www.cnblogs.com/witton/archive/2013/05/05/6868973.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值