传递函数作为参数,用于比较cpp中合并排序中的元素

时间:2016-05-05 16:48:41

标签: c++ arrays sorting templates comparator

编辑1 根据以下评论,我现在尝试使用functors来实现。我仍然被卡住了,所以任何形式的帮助都会受到赞赏。这是我的实施:

mysorting.h

................
#include<myutils.h>
// =================================
// the actual class

class Sorting {
    public:
        template <typename T, typename Func> static void mergeSort(T *, int, Func);
};

template static void Sorting::mergeSort<int, CompareInt>(int *, int, CompareInt);
......................

所以,我将第三个参数作为functor传递给我myutils.h。另外,我已将mergeSort的模板实例化为int。 此外,我已经实例化了合并函数的模板,我用它来合并myutils.h中的数组。以下是我myutils.h

的摘录
................
template <typename T, typename Func> void merge(T[], T[], int, T[], int, Func);

// functor for comparing he integers
struct CompareInt {
    int operator() (int a, int b) {
        return a-b;
    }
};

template void merge<int, CompareInt>(int[], int[], int, int[], int, CompareInt);
........................

myutils.cpp的摘录如下:

.......................
template <typename T, typename Func> void merge(T t[], T first[], int fL, T sec[], int sL, Func compar) {

    int i = 0;
    int j = 0;
    int k = 0;

    // while both the arrays have the elements left ..
    while (j < fL && k < sL) {
        if (compar(first[j], sec[k]) < 0) {
            memcpy(t + i, sec + j, sizeof(T));
            i++; j++;
        } else {
            memcpy(t + i, sec + k, sizeof(T));
            i++; k++;
        }
    }

    ...........
    }
}
.......................

mysorting.cpp的摘录如下:

...............................
class Sorting {
    public:
        template <typename T, typename Func> static void mergeSort(T *, int, Func);
};

template <typename T, typename Func> void Sorting::mergeSort(T *arr, int l, Func compar) { ...}
..........................

我只是打电话:

CompareInt c;
Sorting::mergeSort(arr, 5, c);

运行sort函数。当我尝试使用Makefile编译代码时,出现以下错误:

g++ -c -g -Wall -I./include -c src/mysorting.cpp  -o src/mysorting.o
In file included from src/mysorting.cpp:2:0:
./include/myutils.h: In instantiation of ‘void merge(T*, T*, int, T*, int, Func) [with T = int; Func = CompareInt]’:
./include/myutils.h:19:79:   required from here
./include/myutils.h:19:79: error: explicit instantiation of ‘void merge(T*, T*, int, T*, int, Func) [with T = int; Func = CompareInt]’ but no definition available [-fpermissive]
 template void merge<int, CompareInt>(int[], int[], int, int[], int, CompareInt);
                                                                               ^
./include/myutils.h: In instantiation of ‘void merge(T*, T*, int, T*, int, Func) [with T = int; Func = CompareInt]’:
./include/myutils.h:19:79:   required from here
./include/myutils.h:19:79: error: explicit instantiation of ‘void merge(T*, T*, int, T*, int, Func) [with T = int; Func = CompareInt]’ but no definition available [-fpermissive]
./include/myutils.h: In instantiation of ‘void merge(T*, T*, int, T*, int, Func) [with T = int; Func = CompareInt]’:
./include/myutils.h:19:79:   required from here
./include/myutils.h:19:79: error: explicit instantiation of ‘void merge(T*, T*, int, T*, int, Func) [with T = int; Func = CompareInt]’ but no definition available [-fpermissive]
make: *** [src/mysorting.o] Error 1

你能给我一些暗示吗?

ORIGINAL

我正在尝试在cpp中的类Sorting中编写一个静态函数来实现合并排序。我已经实现了合并排序来排序整数数组。现在,我尝试使用Templates实现合并排序,以对任何数据类型的数组进行排序。为此,我试图在compar函数中将另一个参数作为mergeSort函数传递。以下是实施:

头文件如下:

................
class Sorting {
    public:
        template <typename T> static void mergeSort(T *,int, int (*)(const void*,const void*));
};
................

cpp文件如下:

class Sorting {
    public:
        template <typename T> static void mergeSort(T *,int, int (*)(const void*,const void*));
};

.......

template <typename T> void Sorting::mergeSort(T *arr, int l, int (*compar)(const void*,const void*)) {
    // if the lengh of the array is 1, it is already sorted. Case, when the array is
    // empty
    if (l <= 1) {
        return;
    }

    // else, we divide the arrays and recurse..
    T *left = new T[l/2];
    T *right = new T[l - l/2];

    // copying the values into the left and the right arrays..
    memcpy(left, arr, l/2 * sizeof(T));
    memcpy(right, arr + l/2, (l - l/2) * sizeof(T));

    // running merge sort on the lef tand the right arrays separately ..
    mergeSort(left, l/2, compar);
    mergeSort(right, l - l/2, compar);

    merge(arr, left, l/2, right, l - l/2, compar);
}

merge功能的实现如下:

template <typename T> void merge(T t[], T first[], int fL, T sec[], int sL, int (*compar)(const void*,const void*)) {

    int i = 0;
    int j = 0;
    int k = 0;

    // while both the arrays have the elements left ..
    while (j < fL && k < sL) {
        if ((*compar)(first + j, sec + k) < 0) {
            memcpy(t + i, sec + j, sizeof(T));
            i++; j++;
        } else {
            memcpy(t + i, sec + k, sizeof(T));
            i++; k++;
        }
    }

    // while only the first array has the elements left
    while(j < fL) {
        memcpy(t + i, sec + j, sizeof(T));
        i++; j++;
    }

    // while only the second array has the elements left
    while(k < fL) {
        memcpy(t + i, sec + k, sizeof(T));
        i++; k++;
    }
}

最后,我的main.cpp如下:

................
int compare(const void *a, const void *b) {
    return ( *(int*)a - *(int*)b );
}

int main() {
    int arr[5] = {5,4,3,2,1};
    Sorting::mergeSort(arr, 5, compare);    
}
...............

当我尝试使用Makefile编译代码时,它会出现以下错误:

Undefined symbols for architecture x86_64:
  "void Sorting::mergeSort<int>(int*, int, int (*)(void const*, void const*))", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [a.out] Error 1

当我专门为整数运行我的函数时,代码被成功编译,但现在我遇到了一些麻烦。有什么想法吗?

0 个答案:

没有答案