2012-12-03 62 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”来声明接口中的所有函数都是抽象的。 –