2010-02-24 105 views
3

假設我有一個函數模板,在主函數我寫了一行StrCompare
默認模板參數

template<typename T=NonCaseSenCompare>//NonCaseSenCompare is a user defined class look at the detailed code below. 
int StrCompare(char* str1, char* str2) 
{ 
... 
} 

現在

char* str1="Zia"; 
char* str2="zia"; 
int result=StrCompare(str1,str2); 

它應該工作,因爲我們提供了一個默認的模板參數,但它不會
編譯器給出以下錯誤
沒有匹配函數調用`StrCompare(char * &,char * &) 「 現在詳細的代碼由

#include<iostream.h> 
class CaseSenCompare 
{ 
public: 
static int isEqual(char x, char y) 
{ 
return x==y; 
} 
}; 
class NonCaseSenCompare 
{ 
public: 
static int isEqual(char x,char y) 
{ 
char char1=toupper(x); 
char char2=toupper(y); 
return char1==char2; 
} 
}; 
template<typename T=NonCaseSenCompare> 
int StrCompare(char* str1, char* str2) 
{ 
for(int i=0;i < strlen(str1)&& strlen(str2);i++) 
{ 
if(!T::isEqual(str1[i],str2[i])) 
return str1[i]-str2[i]; 
} 
return strlen(str1)-strlen(str2); 
} 

main() 
{ 
char* ptr1="Zia ur Rahman"; 
char* ptr2="zia ur Rahman"; 
int result=StrCompare(ptr1,ptr2);//compiler gives error on this line 
cout<<result<<endl; 
system("pause"); 
} 

如果我寫

int result=StrCompare<>(ptr1,ptr2); 

編譯器會發出相同的錯誤消息給出。

+3

我不認爲我們將永遠擺脫了「乾草親愛的!」 :D – 2010-02-24 18:21:37

+0

@哈桑:再看一遍。 – 2010-02-24 18:26:03

回答

5

由於gfAndreyT已寫入,因此不能使用函數模板的默認模板參數。但是,如果你把你的比較成函數對象,你仍然可以使用函數默認參數:

template<typename Comp> 
int StrCompare(char* str1, char* str2, Comp = NonCaseSenCompare()) 
{ 
    ... 
} 

現在,您可以撥打StrCompare()這樣

StrCompare("abc","aBc",CaseSenCompare()); 

或像這樣:

StrCompare("abc","aBc"); // uses NonCaseSenCompare 

比較器則必須如下所示:

struct CaseSenCompare { 
    bool operator()(char x, char y) const {return x==y;} 
}; 

據此調整StrCompare()

+0

是,我已經明白了,我們不能提供功能模板的默認模板參數。張貼複製和粘貼樣板/逐字回答多個問題時,由於 – 2010-02-24 18:48:41

4

§14.1/ 9

默認模板參數不應 在一個函數模板 聲明或函數模板 定義中指定,也沒有在的 模板參數列表定義 模板的成員 模板。

一個簡單的變通辦法將它移動到一個類:

template<typename T=NonCaseSenCompare> 
struct StrCompare { 
    static int compare(char* str1, char* str2) { /* ... */ } 
}; 
+0

這麼想,雖然不確定。 – 2010-02-24 18:29:33

+0

那麼在這裏我們指定默認的模板參數 – 2010-02-24 18:32:34

2

首先,函數模板不支持默認模板參數,只有類模板做。

其次,即使所有模板參數都有默認參數,您仍然必須指定空的<>來引用該類模板。

+0

難道意味着我們不能給默認模板參數的函數模板的情況下,我們只能給默認模板參數中的類成員函數呢? – 2010-02-24 18:43:04

+0

再仔細想想,我們的老師說我們可以做到這一點 – 2010-02-24 18:45:22

+0

我有一點,是你的權利,我們不能給默認模板參數的函數模板的情況下 – 2010-02-24 18:49:28

0

我用的是下招;

可以說你想擁有的功能像這樣

template <typename E, typename ARR_E = MyArray_t<E> > void doStuff(ARR_E array) 
{ 
    E one(1); 
    array.add(one); 
} 

,你將不會被允許的,但我接下來做的方式:

template <typename E, typename ARR_E = MyArray_t<E> > 
class worker { 
public: 
    /*static - as you wish */ ARR_E* parr_; 
    void doStuff(); /* do not make this one static also, MSVC complains */ 
}; 

template <typename E, typename ARR_E> 
void worker::doStuff<E, ARR_E>::getChunks() 
{ 
    E one(1); 
    parr_->add(one); 
} 

所以這樣你可以使用它像這樣。

MyArray_t my_array; 
worker<int> w; 
w.parr_ = &arr; 
w.doStuff(); 

因爲我們可以看到沒有必要明確設置第二個參數。 也許它會對某人有用。

+0

要小心,這些往往會被標記爲在社區「垃圾」。 – Kev 2011-07-23 12:24:40