试图将函数从类传递给可变参数模板函数

问题描述 投票:0回答:1

所以我有一个小组项目,正在比较各种排序功能的排序时间。我试图通过使用可变参数模板函数减少复制/粘贴代码的数量。我已经阅读了所有可以在Google上找到的有关它们以及如何将函数作为参数传递的内容。从字面上看这是几天的工作,我似乎无法使这项工作。我已经可以在类之外传递在我的主cpp文件中定义的函数,但是我不能使其对属于类的函数起作用。

我的小组要求我放弃这个想法(我们的时间已经用完了,但是我感觉我已经很接近实现它了。如果有人可以提供语法帮助,我将非常感激。我还尝试使用功能库中的功能类型,这是半可行的唯一方法。我确实在堆栈溢出上发现了this问题,并且那个家伙在使用'&'时遇到了相同的错误,但是我仍然似乎无法使它起作用:

void run_timer(function<void(vector<int> &array, int size)> sort_func, vector<int> &array, int size){

for (int i = 0; i < size; i++)
{
    cout << array[i];
}
cout << endl << endl;
//timer start
auto start1 = high_resolution_clock::now();

//call function to time
sort_func(array, size);

//timer end
auto stop1 = high_resolution_clock::now();

//calculate execution time
auto duration1 = duration_cast<microseconds>(stop1 - start1);       //Output: Microseconds  
auto duration_sec = duration_cast<seconds>(stop1 - start1);         //Output: Seconds

cout << "Array length N = " << size << " took " << duration1.count() << " microseconds.";

//TODO: ***write results to file***}

我想要的是在一个单独的头文件中传递一个名为“ Sorts”的类的函数,例如InsertionSort。还有另一个称为“数据”的类,其中包含测试向量。 (不知道为什么我的小组将它们放在单独的文件夹中,或者即使有所作为)。我想做类似的事情:

run_timer(InsertionSort, vector_to_sort, size_of_vector);

我知道当前功能不是模板,我尝试过并且无法完全获得它。我希望如此,因为其他功能(例如“合并排序”)都需要额外的参数。

这是我尝试的最后一个版本:

template<class Func, class T, class U>
void run_timer(Func sort_func, U)
{
    int size = array.size();
    //timer start
    auto start1 = high_resolution_clock::now();

    //call function to time
    sort_func(array, size);     //***add extra variables here if needed? or we may have to make all of the sort functions template classes instead

    //timer end
    auto stop1 = high_resolution_clock::now();

    //calculate execution time
    auto duration1 = duration_cast<microseconds>(stop1 - start1);       //Output: Microseconds
    auto duration_sec = duration_cast<seconds>(stop1 - start1);         //Output: Seconds
}

//run_timer is a variadic template function that essentially
// allows the base version of run_timer to be overloaded.
// This allows all three vectors to be passed and processed
// by the run_timer function.
// For example, to call selection sort in main:
// run_timer(SelectionSort, sorted, backwards, shuffled)

template<class Func, class T, class U, class...Args>
void run_timer(Func sort_func, Args... args)
{
    int size = array.size();
    //timer start
    auto start1 = high_resolution_clock::now();

    //call function to time
    sort_func(array, size);     //***add extra variables here if needed? or we may have to make all of the sort functions template classes instead

    //timer end
    auto stop1 = high_resolution_clock::now();

    //calculate execution time
    auto duration1 = duration_cast<microseconds>(stop1 - start1);       //Output: Microseconds
    auto duration_sec = duration_cast<seconds>(stop1 - start1);         //Output: Seconds

    //***write results to file***

}

[如果有人可以提供帮助,我肯定会感激的。抱歉,这与我之前链接的内容相似,但是我真的不明白我在做什么错。

我将发布我们拥有的所有代码,以防万一。

#include <iostream>
#include <cstdlib>
#include <random>
#include <chrono>
#include <cctype>
#include <vector>
#include <algorithm>
#include <functional>

#include "Sorts.h"

void shuffle_array(vector<int>& shuffled);
template<template <typename, typename ...> typename , typename U, typename int, typename ...>
void run_timer(function<void(U, int)> sort_func, vector<int>& array, int size);

using namespace std;
using namespace std::chrono;

int main()
{
    Sorts* sort_function = new Sorts();
    Sorts sort_obj;
    Data data_array;

    int length_N = 0;
    int num_datasets = sort_obj.num_datasets;
    int dataset = 9;
    int mid = dataset / 2;

    //for every dataset, small through infinite, create and initialize sorted, backwards, 
    //and shuffled arrays:
    for (int i = 0; i < num_datasets; i++)
    {
        //array length N
        length_N = sort_obj.dataset_sizes[i];

        //create array of length N, with value range 0 through(N - 1); sorted
        vector<int> sorted(length_N);
        for (int j = 0; j < length_N; j++)
        {
            sorted[j] = j;
        }

        //create array of length N, reverse values
        vector<int> backwards = sorted;
        reverse(backwards.begin(), backwards.end());

        //create array of length N, shuffled array
        vector<int> shuffled = sorted;
        shuffle_array(shuffled);

        //copy vectors to data class vectors
        if (i == 0)
        {
            data_array.copyVector(sorted, data_array.dataSmall, length_N);
            data_array.copyVector(backwards, data_array.dataSmallRev, length_N);
            data_array.copyVector(shuffled, data_array.dataSmallRand, length_N);
            //copy of shuffled array length_N for records
            vector<int> shuffled_small = shuffled;

            cout << "data[0] = " << data_array.dataSmall[0] << endl;
            cout << "data[" << length_N - 1 << "] = " << data_array.dataSmall[length_N - 1] << endl;

            cout << "data[0] = " << data_array.dataSmallRev[0] << endl;
            cout << "data[" << length_N - 1 << "] = " << data_array.dataSmallRev[length_N - 1] << endl;
            cout << "shuffled array = ";
            for (int n = 0; n < length_N; n++)
            {
                cout << data_array.dataSmallRand[n] << " ";
            }
            cout << endl << endl;
        } else if (i == 1)
        {
            data_array.copyVector(sorted, data_array.dataMid, length_N);
            data_array.copyVector(backwards, data_array.dataMidRev, length_N);
            data_array.copyVector(shuffled, data_array.dataMidRand, length_N);
            vector<int> shuffled_Mid = shuffled;
        } else if (i == 2)
        {
            data_array.copyVector(sorted, data_array.dataMidLarge, length_N);
            data_array.copyVector(backwards, data_array.dataMidLargeRev, length_N);
            data_array.copyVector(shuffled, data_array.dataMidLargeRand, length_N);
            vector<int> shuffled_MidLarge = shuffled;
        } else if (i == 3)
        {
            data_array.copyVector(sorted, data_array.dataLarge, length_N);
            data_array.copyVector(backwards, data_array.dataLargeRev, length_N);
            data_array.copyVector(shuffled, data_array.dataLargeRand, length_N);
            vector<int> shuffled_Large = shuffled;
        } else if (i == 4)
        {
            data_array.copyVector(sorted, data_array.dataMega, length_N);
            data_array.copyVector(backwards, data_array.dataMegaRev, length_N);
            data_array.copyVector(shuffled, data_array.dataMegaRand, length_N);
            vector<int> shuffled_Mega = shuffled;
        } else if (i == 5)
        {
            data_array.copyVector(sorted, data_array.dataSuperMega, length_N);
            data_array.copyVector(backwards, data_array.dataSuperMegaRev, length_N);
            data_array.copyVector(shuffled, data_array.dataSuperMegaRand, length_N);
            vector<int> shuffled_SuperMega = shuffled;
        } else if (i == 6)
        {
            data_array.copyVector(sorted, data_array.dataUltraMega, length_N);
            data_array.copyVector(backwards, data_array.dataUltraMegaRev, length_N);
            data_array.copyVector(shuffled, data_array.dataUltraMegaRand, length_N);
            vector<int> shuffled_UltraMega = shuffled;
        } else if (i == 7)
        {
            data_array.copyVector(sorted, data_array.dataHoldUp, length_N);
            data_array.copyVector(backwards, data_array.dataHoldUpRev, length_N);
            data_array.copyVector(shuffled, data_array.dataHoldUpRand, length_N);
            vector<int> shuffled_HoldUp = shuffled;
        } else if (i == 8)
        {
            data_array.copyVector(sorted, data_array.dataInifite, length_N);
            data_array.copyVector(backwards, data_array.dataInifiteRev, length_N);
            data_array.copyVector(shuffled, data_array.dataInifiteRand, length_N);
            vector<int> shuffled_Infinite = shuffled;

            cout << endl;
            cout << "data[0] = " << data_array.dataInifite[0] << endl;
            cout << "data[" << length_N - 1 << "] = " << data_array.dataInifite[length_N - 1] << endl;

            cout << "data[0] = " << data_array.dataInifiteRev[0] << endl;
            cout << "data[" << length_N - 1 << "] = " << data_array.dataInifiteRev[length_N - 1] << endl;

            cout << "data[0] = " << data_array.dataInifiteRand[0] << endl;
            cout << "data[" << length_N - 1 << "] = " << data_array.dataInifiteRand[length_N - 1] << endl << endl;

        } else
        { cout << "Error: You suck at coding. "; }



        //TODO: ***saved shuffled array! (write to file)***
        //TODO: Need to figure out how to call functions from the header file
//-------------------------------------------------------------------------------------------------
//run each set of data 9 times for each sort function. store data in vector to get median.
//-------------------------------------------------------------------------------------------------

//***********************************Insertion Sort (small)****************************************

    //---------------Sorted---------------

        vector<int> insertion_vect1(dataset);           //holds the 9 timed values to find median
        for (int k = 0; k < dataset; k++)
        {
            //timer start
            auto start1 = high_resolution_clock::now();

            //call function to time
            sort_function->InsertionSort(data_array.dataSmall, length_N);

            //timer end
            auto stop1 = high_resolution_clock::now();

            //calculate execution time
            auto duration1 = duration_cast<microseconds>(stop1 - start1);       //Output: Microseconds  
            auto duration_sec = duration_cast<seconds>(stop1 - start1);         //Output: Seconds

            cout << "Array length N = " << length_N << " took " << duration1.count() << " microseconds." << endl;
            insertion_vect1[k] = duration1.count();

        }
        //sort array of times to get median
        sort_function->InsertionSort(insertion_vect1, dataset);
        for (int l = 0; l < dataset; l++)
        {
            cout << insertion_vect1[l] << " ";
        }
        int small_ins_sorted_mTime = insertion_vect1[mid];
        cout << endl << "median for insertion sort (small, sorted) = " << small_ins_sorted_mTime << endl;

        //---------------Reverse---------------

        vector<int> insertion_vect2(dataset);           //holds the 9 timed values to find median
        for (int k = 0; k < dataset; k++)
        {
            //timer start
            auto start1 = high_resolution_clock::now();

            //call function to time
            sort_function->InsertionSort(data_array.dataSmallRev, length_N);

            //timer end
            auto stop1 = high_resolution_clock::now();

            //calculate execution time
            auto duration1 = duration_cast<microseconds>(stop1 - start1);       //Output: Microseconds  
            auto duration_sec = duration_cast<seconds>(stop1 - start1);         //Output: Seconds

            cout << "Array length N = " << length_N << " took " << duration1.count() << " microseconds." << endl;
            insertion_vect2[k] = duration1.count();

        }
        //sort array of times to get median
        sort_function->InsertionSort(insertion_vect2, dataset);
        for (int l = 0; l < dataset; l++)
        {
            cout << insertion_vect2[l] << " ";
        }
        int small_ins_rev_mTime = insertion_vect2[mid];
        cout << "median for insertion sort (small, reverse) = " << small_ins_rev_mTime << endl;

        //---------------Random---------------

        vector<int> insertion_vect3(dataset);           //holds the 9 timed values to find median
        for (int k = 0; k < dataset; k++)
        {
            //timer start
            auto start1 = high_resolution_clock::now();

            //call function to time
            sort_function->InsertionSort(data_array.dataSmallRand, length_N);

            //timer end
            auto stop1 = high_resolution_clock::now();

            //calculate execution time
            auto duration1 = duration_cast<microseconds>(stop1 - start1);       //Output: Microseconds  
            auto duration_sec = duration_cast<seconds>(stop1 - start1);         //Output: Seconds

            cout << "Array length N = " << length_N << " took " << duration1.count() << " microseconds." << endl;
            insertion_vect3[k] = duration1.count();

        }
        //sort array of times to get median
        sort_function->InsertionSort(insertion_vect3, dataset);
        for (int l = 0; l < dataset; l++)
        {
            cout << insertion_vect3[l] << " ";
        }
        int small_ins_rand_mTime = insertion_vect3[mid];
        cout << "median for insertion sort (small, shuffled) = " << small_ins_rand_mTime << endl;

        //I would love to have a way to automate this so we don't have to screw around
        //with changing all these variables for each block. 

//***********************************Insertion Sort (mid)****************************************
        //---------------Sorted---------------
        //---------------Reverse---------------
        //---------------Random---------------

//***********************************QuickSort (small)****************************************
    //WHY DOESNT THIS STUPID THING SORT? WHO WROTE THIS GARBAGE? (oh yeah i did) :(
    //---------------Sorted---------------

        vector<int> quick_vect1(dataset);           //holds the 9 timed values to find median
        for (int k = 0; k < dataset; k++)
        {
            //timer start
            auto start1 = high_resolution_clock::now();

            //call function to time (Quicksort_med(A, 0, (length - 1)))
            sort_function->quicksort_med(data_array.dataSmall, 0, length_N - 1);

            //timer end
            auto stop1 = high_resolution_clock::now();

            //calculate execution time
            auto duration1 = duration_cast<microseconds>(stop1 - start1);       //Output: Microseconds  
            auto duration_sec = duration_cast<seconds>(stop1 - start1);         //Output: Seconds

            cout << "Array length N = " << length_N << " took " << duration1.count() << " microseconds." << endl;
            quick_vect1[k] = duration1.count();

        }
        //sort array of times to get median
        sort_function->quicksort_med(quick_vect1, 0, dataset - 1);
        for (int l = 0; l < dataset; l++)
        {
            cout << quick_vect1[l] << " ";
        }
        int small_qs_sorted_mTime = quick_vect1[mid];
        cout << endl << "median for insertion sort (small, sorted) = " << small_qs_sorted_mTime << endl;


        system("pause");
        return 0;
    }
}

void shuffle_array(vector<int>& shuffled)
{
    // get seed value:
    unsigned seed = system_clock::now().time_since_epoch().count();
    //shuffle values
    shuffle(shuffled.begin(), shuffled.end(), default_random_engine(seed));
}


// run_timer takes a function (sort_func) as a parameter, which itself takes a vector (by reference)
// and an int. It also takes an int vector (array) and an int (size). For example, 
// run_timer(InsertionSort, vector_name, length_N) could be called in main which would 
// execute InsertionSort on the passed vector. This will work on a function that is 
// located within the main file, but I cannot get it to run on anything within a class. 
// the idea was to be able to write the main with a minimum amount of copy/paste and 
// variable name tweaking, thus minimizing the amount of errors and bugs due to missing
// the things needing to be changed and inserted in each repeated block.
/*
template<template <typename, typename ...> typename T, typename U, typename int, typename ...> 
void run_timer(function<void(vector<int> &array, int size)> sort_func, vector<int> &array, int size)

{
    //int length = array.size();
    for (int i = 0; i < size; i++)
    {
        cout << array[i];
    }
    cout << endl << endl;
    //timer start
    auto start1 = high_resolution_clock::now();

    //call function to time
    sort_func(array, size);

    //timer end
    auto stop1 = high_resolution_clock::now();

    //calculate execution time
    auto duration1 = duration_cast<microseconds>(stop1 - start1);       //Output: Microseconds
    auto duration_sec = duration_cast<seconds>(stop1 - start1);         //Output: Seconds

    cout << "Array length N = " << size << " took " << duration1.count() << " microseconds.";

    //TODO: ***write results to file***
}

这是头文件:


#ifndef SORTS_H
#define SORTS_H

#include <iostream>
#include <cstdlib>
#include <random>
#include <chrono>
#include <cctype>
#include <vector>
#include <functional>
#include <string>

using namespace std;
using namespace std::chrono;

class Data {

public:
    const int small = 10;
    const int mid = 100;
    const int midLarge = 500;
    const int large = 1000;
    const int mega = 2000;
    const int supermega = 5000;
    const int ultramega = 10000;
    const int holdUp = 50000;
    const int infinite = 100000;

    int num_datasets = 9;
    vector<int>dataset_sizes{ small, mid, midLarge, large, mega, supermega, ultramega, holdUp, infinite };

    Data() {};
    ~Data() {};
    vector<int> dataSmallRand;
    vector<int> dataMidRand;
    vector<int> dataMidLargeRand;
    vector<int> dataLargeRand;
    vector<int> dataMegaRand;
    vector<int> dataSuperMegaRand;
    vector<int> dataUltraMegaRand;
    vector<int> dataHoldUpRand;
    vector<int> dataInifiteRand;

    vector<int> dataSmall;
    vector<int> dataMid;
    vector<int> dataMidLarge;
    vector<int> dataLarge;
    vector<int> dataMega;
    vector<int> dataSuperMega;
    vector<int> dataUltraMega;
    vector<int> dataHoldUp;
    vector<int> dataInifite;

    vector<int> dataSmallRev;
    vector<int> dataMidRev;
    vector<int> dataMidLargeRev;
    vector<int> dataLargeRev;
    vector<int> dataMegaRev;
    vector<int> dataSuperMegaRev;
    vector<int> dataUltraMegaRev;
    vector<int> dataHoldUpRev;
    vector<int> dataInifiteRev;

    void copyVector(const vector<int>& vect, vector<int>& vector, int size)
    { // you can access and enter the values thru main. The values are public. getters and setters will get messy. select your size and vector.
        for (int i = 0; i < size; i++)
        {
            vector.push_back(vect[i]);
        }

        //testChrono(vector, size);
    }

    void testChrono(vector<int> v, int s)
    {
        cout << " *********Before Sort*********" << endl
            << endl;
        print(v, s);

        auto start = chrono::steady_clock::now();

        //sorting function goes here

        auto end = chrono::steady_clock::now();
        double elapsed_time = double(chrono::duration_cast<chrono::nanoseconds>(end - start).count());
        cout << "elapsed Time (s): " << elapsed_time / 1e9 << endl;

        cout << " *********After Sort**********" << endl << endl;
        print(v, s);
    }
    void print(vector<int>& vector, int size)
    { //testing
        for (int i = 0; i < size; i++)
        {
            cout << "Element " << i + 1 << ": " << vector.at(i) << endl;
        }
    }
};

class Sorts : public Data {
public:
    //constructor
    Sorts() {};
    //destructor
    ~Sorts() {};
    void printArray(vector<int> A);
    void swap(int*, int*);
    void run_timer(function<void(vector<int> array, int size)>sort_func, vector<int> array);

    //insertion sort
    void InsertionSort(vector<int>&, int);//needs & to sort actual vector, not a copy sent to the function

    //Bubble sort
    void bubbleSort(vector<int>, int);

    //Quick Sort
    void quickmain();
    void mainMenu();
    void buildArray(vector<int>, int, bool);
    int partition1(vector<int>, int, int);
    void quicksort(vector<int>, int, int);
    void quicksort_med(vector<int>, int, int);
    int partition_med(vector<int>, int, int);
    void random_array(vector<int>, int);

    //heap sort
    void max_heapify(vector<int>&, int, int);
    void buildMaxHeap(vector<int>&, int);
    void ascendingHeapSort(vector<int>&, int);

    //Merge Sort
    void Fuse(vector<int>, int, int, int);
    void MergeS(vector<int>, int, int);

    //Selection sort
    void selectionSort(vector<int>, int);

};


//*****************************Utility Functions********************************

void Sorts::run_timer(function<void(vector<int> array, int size)>sort_func, vector<int> array)
{
    int length = array.size();
    for (int i = 0; i < length; i++)
    {
        cout << array[i];
    }
    cout << endl << endl;
    //timer start
    auto start1 = high_resolution_clock::now();

    //call function to time
    sort_func(array, length);

    //timer end
    auto stop1 = high_resolution_clock::now();

    //calculate execution time
    auto duration1 = duration_cast<microseconds>(stop1 - start1);       //Output: Microseconds  
    auto duration_sec = duration_cast<seconds>(stop1 - start1);         //Output: Seconds

    cout << "Array length N = " << length << " took " << duration1.count() << " microseconds.";

    //TODO: ***write results to file***
}
void Sorts::printArray(vector<int> A)
{
    for (int i = 1; i < A.size(); i++)
    {
        cout << A[i] << ",";
    }
    cout << endl;
}
void Sorts::swap(int* a, int* b) // using reference by pointer for changes throughout function
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

//*****************************Quicksort Functions********************************

//Quick Sort
void Sorts::quickmain()
{
    const int   FIRST = 1,          //constants for menu option choices
        RANDOM = 2,
        MEDIAN = 3,
        EXIT = 4;
    const char  OWN_ARRAY = 'A',
        RAND_ARRAY = 'B';
    char choice1;
    int choice2 = 0;
    int length = 0;
    bool finished = false;

    cout << "**********Quicksort Program**********" << endl << endl;

    cout << "Would you like to:" << endl << endl;
    cout << "A. Enter my own list of values" << endl;
    cout << "B. Generate a random list" << endl << endl;
    cout << "Please enter A or B: ";
    //discard leading white space
    cin >> ws;
    //get user's choice of entering own values or generating random values
    cin >> choice1;
    //clear character in buffer following input, if any
    cin.ignore();

    cout << endl << "How many numbers would you like to sort?  ";
    cin >> length;

    //input array
    vector<int>A(length);

    //Switch statement to let user input values or create an array of random values
    switch (toupper(choice1))
    {
    case OWN_ARRAY:
        buildArray(A, length, finished);
        break;
    case RAND_ARRAY:
        random_array(A, length);
        break;
    default: cout << "error";
    }

    //display main menu options
    mainMenu();
    //get user's selection from menu
    cin >> choice2;

    //sort list for testing
    quicksort(A, 0, (length - 1));
    //timer start
    auto start1 = high_resolution_clock::now();

    //switch statement for Main Menu choices. Determines how pivot is selected.
    switch (choice2)
    {
    case FIRST:
        quicksort(A, 0, (length - 1));                                          //length-1 because array index starts at 0
        break;
    case MEDIAN:
        quicksort_med(A, 0, (length - 1));                                      //length-1 because array index starts at 0
        break;
    case EXIT:
        break;
    default:
        cout << "Don't be stupid. Please enter a menu option using 1-4: ";
        cin >> choice2;
    }
    auto stop1 = high_resolution_clock::now();                              //timer end
    auto duration1 = duration_cast<microseconds>(stop1 - start1);           //calculate execution time
    auto duration_sec = duration_cast<seconds>(stop1 - start1);

    //print sorted values
    //cout << endl;
    //for (int i = 0; i < length; i++)
        //cout << A[i] << " " << endl;
    cout << endl;
    cout << "Quicksort took " << duration1.count() << " microseconds." << endl;
    cout << endl;
    //pause program to view output
    cin.get();
}
//menu options that allow the user to select how the pivot is chosen
void Sorts::mainMenu()
{
    cout << endl;
    cout << "Choose a method for selecting the pivot:" << endl;
    cout << "1 - First element in the list" << endl;
    cout << "2 - A random element in the array" << endl;
    cout << "3 - The median" << endl;

    cout << "4 - Exit" << endl << endl;

    cout << "Enter a value 1-4: ";
}
//stores user's values in array
void Sorts::buildArray(vector<int>A, int length, bool finished)
{
    {
        int i = 0;
        int val = 0;
        cout << endl << "Please enter your list, one number at a time:" << endl;
        cout.flush();

        while (finished == false)       //get input from user
        {
            cin >> ws;                  //discard leading white space
            int x = cin.peek();         //check validity
            if (ispunct(x))             //user entered a space
            {
                string exit;            //get ! out of buffer
                cin >> exit;
                finished = true;        //set flag to terminate entry sequence
            } else if (isdigit(x))
            {
                cin >> val;             //store input
                A[i] = val;             //add value to array
                i += 1;
                if (i == length)
                    finished = true;
            } else
            {
                string str;
                cin >> str;
                finished = false;
                cout << "Invalid input. Punch yourself in the face and enter a valid whole number: ";
            }

        }
    }
}
//regular quicksort function
void Sorts::quicksort(vector<int>A, int left, int right)
{
    int q;
    if (left < right)
    {
        q = partition1(A, left, right);
        quicksort(A, left, q);
        quicksort(A, (q + 1), right);
    }
}
//quicksort taking the median of first, middle, and last elements 
void Sorts::quicksort_med(vector<int>A, int left, int right)
{
    int q;
    if (left < right)
    {
        q = partition_med(A, left, right);
        //cout << "q = " << q << endl;
        //cout << "entering quicksort_med with variables left = " << left << " and q = " << q << endl;
        quicksort_med(A, left, q);
        //cout << "entering quicksort_med with variables q + 1 = " << q + 1 << " and right = " << right << endl;
        quicksort_med(A, (q + 1), right);
    }
}

//regular partition method (Hoare)
int Sorts::partition1(vector<int>A, int left, int right)
{
    //cout << "entered partition1" << endl;
    int pivot = A[left];
    //cout << "pivot = " << pivot << endl;
    int i = left - 1;
    int j = right + 1;
    int temp;

    while (true)
    {
        //find the left-most element that is >= pivot
        do
        {
            i++;
            //cout << "iterating i to i = " << i << endl;
        } while (A[i] < pivot);
        //find rightmost element that is <= pivot
        do
        {
            j--;
            //cout << "decrementing j to j = " << j << endl;
        } while (A[j] > pivot);
        //if pointers cross or are ==
        if (i >= j)
        {
            //cout << "Returning j= " << j << endl;
            return j;
        }
        //once pointers stop, swap elements to correct sides
        //cout << "swapping A[" << i << "] = " << A[i] << endl;
        swap(&A[i], &A[j]);
    }
}

//partition that calculates the median of first, middle, and last elements and swaps the index of the middle value
int Sorts::partition_med(vector<int>A, int left, int right)
{
    //array to hold first, middle, and last elements of the array
    vector<int> arrB(3);
    //get index of middle element. right + 1 gets length of array
    int mid_index = (right + 1) / 2;
    //initialize array with first, middle, and last values
    arrB[0] = A[left];
    arrB[1] = A[mid_index];
    arrB[2] = A[right];
    //sort values
    quicksort(arrB, 0, 2);
    //swap median value with left value, unless the left value is the median, then do nothing
    if (arrB[1] == A[mid_index])
        swap(&A[mid_index], &A[left]);
    else if (arrB[1] == A[right])
        swap(&A[right], &A[left]);

    //cout << "returning partition1 function" << endl;
    return partition1(A, left, right);
}
//populate an array with random numbers for sorting
void Sorts::random_array(vector<int>A, int length)
{
    //srand(time(NULL));
    //int randVal = rand() % (length);
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    default_random_engine generator(seed);
    uniform_int_distribution<int> distribution(1, 100000);

    for (int i = 0; i < length; i++)
    {
        int randVal = distribution(generator);
        A[i] = randVal;
    }
}

//Insertion Sort
//****this is not sorting properly. skipping first element[0]*****
void Sorts::InsertionSort(vector <int>& vector, int sizeOfVector)
{
    int key;
    sizeOfVector = vector.size();
    for (int j = 2; j < sizeOfVector; ++j)
    {
        key = vector[j];
        int i = j - 1;
        while (i > 0 && vector[i] > key)
        {
            vector[i + 1] = vector[i];
            i--;
        }
        vector[i + 1] = key;
    }
}

//there's more functions but the post is too long :(

}
#endif SORTS_H

我知道这篇文章超长,如果有人真正阅读了这篇文章并且可以提供指导,我会给您发送网络脚步。谢谢!

c++ class parameters formatting variadic-templates
1个回答
0
投票

由于您的问题包含更多的代码,所以我想进行筛查,我仅举一个示例,说明如何将函数传递给模板。

#include <iostream>

template <typename F>
void foo(F f) {
    f();
}

struct bar {
    void print() {
        std::cout << "bar\n";
    }
    void baz() {
        foo([&]() { print(); });
    }
};

void print() {
    std::cout << "free\n";
}

int main () {
    foo(print);
    bar b;

    b.baz();
    foo([&]() { b.print(); });
}

可以简单地传递一个自由函数。如果要传递成员函数,可以将其包装在lambda中。

© www.soinside.com 2019 - 2024. All rights reserved.