1.9 循环展开

冒泡排序的展开

void bubbleSort(int* data, int n) {
if( n <= 1)
return;
for(int j = 0; j < n-1; ++j)
if(data[j] > data[j+1])
std::swap(data[j], data[j+1]);
bubbleSort(data, n-1);
}
#include <iostream>
template<int j>
void check_swap(int *data) {
if (data[j] > data[j+1])
std::swap(data[j], data[j+1]);
}
// 不能让j==n
// 因为下一把递归到check_swap的时候
// j+1就超出n了。
template<int n, int j>
void bloop(int *data) {
check_swap<j>(data);
// 本来递归的写法就应该是
// bloop<n, j+1>(data);
// 但是这种写法以是无穷展开
// 所以需要判断j+1 > n
// 如果j+1 > n,然后把第二个模板参数
// 设置为-1
bloop< (j+1 >= n? -1 : n), (j+1 >= n? -1 : j+1)>(data);
}
template<>
void bloop<-1,-1>(int *data) {
}
template<int N>
void bsort(int *data) {
// for (i = 0, i < N-1; check_swap(i,i+1))
// 也就是0, N-1
bloop<N-1, 0>(data);
bsort<N-1>(data);
}
template<>
void bsort<1>(int *data) {
}
template<>
void bsort<0>(int *data) {
}
int main(void) {
int data[] = {4,3,2,1};
bsort<4>(data);
for (auto x : data) {
std::cout << x << std::endl;
}
return 0;
}

代码膨胀

为了实现封装细节,那么可以把上面的bloop/check_swap函数都放到一个类里面,写法如下:

template<int n>
class IntBubbleSortC {
template<int j>
static inline void check_swap ....
template<int n, int j>
static inline void bloop ...
public:
static inline void bsort ...
};
template<>
class IntBubbleSortC<0> {
public:
static inline void sort(int* data) { }
};
int main() {
int data[4] = {3,4,2,1};
IntBubbleSortC<4>::sort(data); // 如此调用
std::cin.get(); return 0;
}

但是这里一定要注意的是类内部的函数定义一定要使用inline函数。否则会导致代码膨胀。