аргументы шаблона по умолчанию в c ++ - PullRequest
3 голосов
/ 24 февраля 2010

Предположим, у меня есть шаблон функции 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);

Компилятор выдает то же сообщение об ошибке.

Ответы [ 4 ]

6 голосов
/ 24 февраля 2010

Поскольку 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() соответственно.

4 голосов
/ 24 февраля 2010

§14.1 / 9

Шаблон-аргумент по умолчанию не должен быть указан в шаблоне функции объявление или шаблон функции определение, ни в шаблон-список параметров определение члена класса шаблон.

Простой обходной путь - переместить его в класс:

template<typename T=NonCaseSenCompare>
struct StrCompare {
    static int compare(char* str1, char* str2) { /* ... */ }
};
2 голосов
/ 24 февраля 2010

Во-первых, шаблоны функций не поддерживают аргументы шаблона по умолчанию, только шаблоны классов.

Во-вторых, даже если все параметры шаблона class имеют аргументы по умолчанию, вам все равно нужно указать пустой <> для ссылки на этот шаблон класса.

0 голосов
/ 23 июля 2011

Я использую следующий трюк;

Допустим, вы хотите иметь такую ​​функцию

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();

как мы видим, нет необходимости явно устанавливать второй параметр. может быть, это кому-нибудь пригодится.

...