假设我有一个功能模板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 *&amp;,char *&amp;)'
现在详细的代码由
#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);
编译器提供相同的错误消息。
答案 0 :(得分:6)
由于gf和AndreyT已经写过,您不能拥有带功能模板的默认模板参数。但是,如果将比较器转换为函数对象,仍可以使用默认函数参数:
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()
。
答案 1 :(得分:4)
§14.1/ 9 :
默认模板参数不得 在函数模板中指定 声明或功能模板 定义,也不是 模板参数列表 一个类成员的定义 模板。
一个简单的解决方法是将它移到一个类中:
template<typename T=NonCaseSenCompare>
struct StrCompare {
static int compare(char* str1, char* str2) { /* ... */ }
};
答案 2 :(得分:2)
首先,函数模板不支持默认模板参数,只有类模板支持。
其次,即使所有类模板参数都有默认参数,您仍然需要指定一个空的<>
来引用该类模板。
答案 3 :(得分: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();
因为我们可以看到不需要显式设置第二个参数。 也许对某人有用。