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

 

 1struct STest
 2{
 3    int a;
 4    int b;
 5    vector<int> vctInt;
 6};```
 7
 8
 9 
10
11我们定义了两个数组:
12
13```cpp
14STest A[20];
15STest B[20];```
16
17
18需要将数组A中的所有内容复制到B数组中,通常我们的做法都是这样:
19
20 
21
22```cpp
23for(size_t i = 0; i < ARRAYSIZE(A); ++i)
24{
25    A[i] = B[i];
26}```
27
28
29这里不能直接使用memcpy,因为STest中有vector类型。但是,如果我们定义的是内置类型的数组,则上面的代码效率较低,而直接使用memcpy会更高效
30
31 
32
33为了解决上面的问题,我们可以使用C++模板对不同的类型进行不同的处理。下面有两种写法:
34
35第一种写法是最容易想到的,就是直接写一个模板,并对这个模板的C++内置类型进行特化处理:
36
37 
38
39```cpp
40template<typename T,size_t N>
41inline void ArrayAssign(T (&A)[N], T (&B)[N])
42{
43    for(size_t i = 0; i < N; ++i)
44        A[i] = B[i];
45}
46
47template<size_t N>
48inline void ArrayAssign(bool (&A)[N], bool (&B)[N])
49{
50    memcpy(A,B,sizeof(A));
51}
52
53template<size_t N>
54inline void ArrayAssign(char (&A)[N], char (&B)[N])
55{
56    memcpy(A,B,sizeof(A));
57}
58
59template<size_t N>
60inline void ArrayAssign(short (&A)[N], short (&B)[N])
61{
62    memcpy(A,B,sizeof(A));
63}
64
65template<size_t N>
66inline void ArrayAssign(int (&A)[N], int (&B)[N])
67{
68    memcpy(A,B,sizeof(A));
69}
70
71template<size_t N>
72inline void ArrayAssign(long long (&A)[N], long long (&B)[N])
73{
74    memcpy(A,B,sizeof(A));
75}
76
77template<size_t N>
78inline void ArrayAssign(unsigned char (&A)[N], unsigned char (&B)[N])
79{
80    memcpy(A,B,sizeof(A));
81}
82
83template<size_t N>
84inline void ArrayAssign(unsigned short (&A)[N], unsigned short (&B)[N])
85{
86    memcpy(A,B,sizeof(A));
87}
88
89template<size_t N>
90inline void ArrayAssign(unsigned int (&A)[N], unsigned int (&B)[N])
91{
92    memcpy(A,B,sizeof(A));
93}
94
95template<size_t N>
96inline void ArrayAssign(unsigned long long (&A)[N],unsigned long long (&B)[N])
97{
98    memcpy(A,B,sizeof(A));
99}

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

 

 

 1template<bool A,typename B,typename C>
 2struct _if{};
 3
 4template<typename B,typename C>
 5struct _if<true,B,C>{ typedef B Type; };
 6
 7template<typename B,typename C>
 8struct _if<false,B,C>{ typedef C Type; };
 9
10template<typename T,size_t N>
11inline size_t ARRAYSIZE(T (&)[N])
12{
13    return N;
14}
15
16template<typename T>
17struct IsInnerType { static const bool Value = false; };
18
19template<>
20struct IsInnerType<bool> { static const bool Value = true; };
21template<>
22struct IsInnerType<char> { static const bool Value = true; };
23template<>
24struct IsInnerType<short> { static const bool Value = true; };
25template<>
26struct IsInnerType<int> { static const bool Value = true; };
27template<>
28struct IsInnerType<long long> { static const bool Value = true; };
29template<>
30struct IsInnerType<unsigned char> { static const bool Value = true; };
31template<>
32struct IsInnerType<unsigned short> { static const bool Value = true; };
33template<>
34struct IsInnerType<unsigned int> { static const bool Value = true; };
35template<>
36struct IsInnerType<unsigned long long> { static const bool Value = true; };
37
38template<typename T,size_t N>
39struct ArrayAssignInnerType
40{
41    static inline void Invoke(T (&A)[N], T (&B)[N])
42    {
43        memcpy(A,B,sizeof(A));
44    }
45};
46
47template<typename T,size_t N>
48struct ArrayAssignCustomType
49{
50    static inline void Invoke(T (&A)[N], T (&B)[N])
51    {
52        for(size_t i = 0; i < N; ++i)
53            A[i] = B[i];
54    }
55};
56
57template<typename T,size_t N>
58inline void ArrayAssign(T (&A)[N], T (&B)[N])
59{
60    _if<IsInnerType<T>::Value,ArrayAssignInnerType<T,N>,ArrayAssignCustomType<T,N> >::Type::Invoke(A,B);
61}

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

 

 

1ArrayAssign(B,A);```
2
3
4以上代码在VC和GCC下编译通过。
5
6 
7
8