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

コンパイラは同じエラー メッセージを表示します。

4

4 に答える 4

6

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()ます。

于 2010-02-24T18:44:06.823 に答える
4

§14.1/9 :

デフォルトの template-argument は、関数テンプレート宣言または関数テンプレート定義、またはクラス テンプレートのメンバーの定義の template-parameter-list で指定してはなりません。

簡単な回避策は、クラスに移動することです。

template<typename T=NonCaseSenCompare>
struct StrCompare {
    static int compare(char* str1, char* str2) { /* ... */ }
};
于 2010-02-24T18:28:37.973 に答える
2

まず、関数テンプレートはデフォルトのテンプレート引数をサポートしておらず、クラス テンプレートだけがサポートしています。

第 2 に、すべてのクラス<>テンプレート パラメーターにデフォルトの引数がある場合でも、そのクラス テンプレートを参照するには空を指定する必要があります。

于 2010-02-24T18:31:48.247 に答える
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();

2番目のパラメータを明示的に設定する必要がないことがわかります。多分それは誰かのために役立つでしょう。

于 2011-07-23T00:07:36.617 に答える