2012-12-03 63 views
1

是否有可能爲在其參數列表中具有模板類的函數創建模板?模板函數:如何使用模板類作爲參數來創建模板函數?

我想爲statSelection()和statInsertion()創建一個模板,它允許我測試不同的排序算法,而不必爲我測試的每種排序算法類型創建單獨的stat函數。 (我的排序算法是模板類)

#include <iostream> 
#include <fstream> 
#include <iomanip> 
#include <cstdlib> 
#include <ctime> 
#include "FileGen.h" 
#include "FileRead.h" 
#include "SelectionSort.h" 
#include "SelectionSort.cpp" 
#include "InsertionSort.h" 
#include "InsertionSort.cpp" 

using namespace std; 

void statSelection(int[], int[], Selection<int>, Selection<int>); 
void statInsertion(int[], int[], Insertion<int>, Insertion<int>); 

int main() 
{ 
    FileGen fileGen; 
    FileRead fileRead; 
    Selection<int> selectHundred; 
    Selection<int> selectThousand; 
    Insertion<int> insertionHundred; 
    Insertion<int> insertionThousand; 
    int valuesHundred[100]; 
    int valuesThousand[1000]; 
    fileGen.generateFiles(); 
    fileRead.readFiles(valuesHundred, valuesThousand); 
    statSelection(valuesHundred, valuesThousand, selectHundred, selectThousand); 
    fileGen.generateFiles(); 
    fileRead.readFiles(valuesHundred, valuesThousand); 
    statInsertion(valuesHundred, valuesThousand, insertionHundred, insertionThousand); 
    system("pause"); 
    return 0; 
} 

void statSelection(int vHundred[], int vThousand[], Selection<int> sHundred, Selection<int> sThousand) 
{ 
    cout << "One Hundred Items" << endl; 
    sHundred.SelectionSort(vHundred, 100); 
    sHundred.selectionSortPreformance(); 
    cout << "One Thousand Items" << endl; 
    sThousand.SelectionSort(vThousand, 1000); 
    sThousand.selectionSortPreformance(); 
} 

void statInsertion(int vHundred[], int vThousand[], Insertion<int> iHundred, Insertion<int> iThousand) 
{ 
    cout << "One Hundred Items" << endl; 
    iHundred.InsertionSort(vHundred, 100); 
    iHundred.insertionSortPreformance(); 
    cout << "One Thousand Items" << endl; 
    iThousand.InsertionSort(vThousand, 1000); 
    iThousand.insertionSortPreformance(); 
} 
+0

你能提供一些簡短的代碼示例,說明你想達到什麼樣的? – juanchopanza

+0

我真的很感謝大家的迴應。讓我試着澄清我所問的:這個驅動程序文件能夠正確地打印出每個排序算法的交換次數和比較次數。排序類是類模板,一切工作正常。我的問題是如何爲模板類創建一個模板作爲參數?我希望能夠調用傳遞插入類或選擇類(或其他排序類)的統計信息,但這兩個類都是模板。沒有多態性可以做到這一點嗎? – Zzz

+0

這是如果你的功能相同的名稱。 –

回答

2

我寧願使用多態性。(不含多態性的溶液可以在水平規則之後發現的)

我會從抽象類(接口)稱爲ISortable<_Tp>同時繼承Insertion<_Tp>Selection<_Tp>,和名稱.InsertionSort.SelectionSort成員函數簡單地作爲.Sort(這將是一個虛擬成員函數Sortable < _Tp>)。

template<typename _Tp> 
class ISortable<_Tp>{ 
public: 
    virtual void Sort(_Tp *, int)=0; // btw functions are usually lowercase 
    virtual void Performance()=0; 
}; 

template<typename _Tp> 
class InsertionSort<_Tp> : public Sortable<_Tp>{ 
//... 
    virtual void Sort(_Tp *, int); 
    virtual void Performance(); 
}; 
//... 

所以你的函數可以這樣寫:

void statSelection(int[], int[], Sortable<int>&, Sortable<int>&); 

void statSelection(int[], int[], Sortable<int>&sHundred, Sortable<int>&) 
{ 
//... 
    sHundred.Sort(vHundred, 100); 
    sHundred.Performance(); 
//... 
} 

解決方案,而多態性:

這是可以做到的,只是名稱都被你的排序和性能功能,同名

然後

template<typename _Tp_sortable> 
void statGeneral(int[], int[], _Tp_sortable sHundred, _Tp_sortable) 
{ 
//... 
    sHundred.Sort(vHundred, 100); 
    sHundred.Performance(); 
//... 
} 

的例子:(林不知道,如果你確實需要的功能後<Selection<int> >的一部分,但我會用它稱呼它)

statGeneral<Selection<int> >(valuesHundred, valuesThousand, selectHundred, selectThousand); 
statGeneral<Insertion<int> >(valuesHundred, valuesThousand, insertionHundred, insertionThousand); 
+0

你能否更詳細地解釋你的第二個建議?在這種情況下,我如何將參數列表傳遞給類模板(即插入) – Zzz

+0

當然,請檢查我的更新,我在這個新表單中複製了主函數中的兩行。如果因爲某種原因無法使用,請告訴我,我會研究它。 –

1

你不清楚你在做什麼,但是這是一個具有類模板參數的函數模板。

// class template 
template <typename T> class Foo {}; 

// function template 
template <typename T> 
T doSomething(const Foo<T>& f) { .... } 

如果你希望能夠指定類模板作爲模板參數,那麼你需要一個「模板的模板參數」:

// class templates 
template <typename T> class Foo {}; 
template <typename T> class Bar {}; 

template <template<class> class T1, class T2> 
T2 doSomething(const T1<T2>& f); 

Foo<int> f; 
Bar<double> b; 
int n = doSomething(f); 
double x = doSomething(b); 
1

像這樣的事情吧?

template <typename T> 
void statSelection(T vHundred[], T vThousand[], Selection<T> sHundred, Selection<T> sThousand); 

template <typename T> 
void statInsertion(T vHundred[], T vThousand[], Insertion<T> iHundred, Insertion<T> iThousand); 
0

可以使用像這樣的一個類:

template <class T> 
class Sortclass 
{ 
public: 
    virtual void sort(T array[] , int size) = 0; 
    virtual void preformance() = 0; 
}; 

template <class T> 
class AsortClass : public Sortclass<T> 
{ 
public: 
    virtual sort(T array[] , int size) 
    { 
     //do stuff 
    } 

    virtual void preformance() 
    { 
     //do stuff 
    } 
}; 

template <class T> 
void stat(T vHundred[], T vThousand[], Sortclass<T>& iHundred, Sortclass<T>& iThousand) 
{ 
    cout << "One Hundred Items" << endl; 
    iHundred.sort(vHundred, 100); 
    iHundred.preformance(); 
    cout << "One Thousand Items" << endl; 
    iThousand.sort(vThousand, 1000); 
    iThousand.preformance(); 
}  

然後你可以繼承這個類並實現排序funktion。 使用此功能,您可以在不更改統計功能的情況下輕鬆更改排序algorythm。

其所謂的戰略格局看: http://en.wikipedia.org/wiki/Strategy_pattern

+0

1.你的代碼在stat函數中是錯誤的。 2.它與我的解決方案沒有區別。 –

+0

不好意思,但是你的班級代碼也是錯誤的......在發帖之前看看我的回答嗎? –

+0

我想我欠你一個解釋爲什麼你的代碼仍然是錯誤的。如果你打算做多態,你需要聲明所有的函數是虛擬的(就像我在我的答案中所做的那樣)。否則程序將總是調用基類中的函數。 (順便說一句,結果是當前鏈接代碼中的錯誤。)另外,建議在聲明後面添加「= 0」來聲明接口中的所有函數都是抽象的。 –