1.エラー報告現象:
1.1。実行されるコード:
string s = "Abcd. ,,cD";
transform(s.begin(), s.end(), s.begin(), tolower);
Tolower関数:大文字を小文字に変換し、それらが文字でない場合は保持します。
1.2。プロンプトエラー:
Line 5: Char 9: fatal error: no matching function for call to 'transform'
transform(s.begin(), s.end(), s.begin(), tolower);
^~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_algo.h:4293:5:
note: candidate template ignored: couldn't infer template argument '_UnaryOperation'
1 error generated.
テンプレートパラメータを推測できなかったことを示します。
2、エラーの理由:
中<cctype>
文のCバージョン函数tolower
:
int tolower(int);
そして<local>
真ん中にも1つを宣言し函数模板tolower
ます:
template <class charT>
charT tolower( charT c , const locale& loc );
これら2つのヘッダーファイルが同時にプログラムに含まれている場合(C ++標準ヘッダーファイルには、他の標準ヘッダーファイルが含まれている場合があります。たとえば<iostream>
、インクルードファイル<locale>
や<cctype>
ヘッダーファイルです。このように、これらの関数は同じ名前空間にあるため、comprises <iostream>
は<locale>
or <cctype>
)を導入する可能tolower
性がありstd
ます。。この場合、== transform
関数(これもテンプレート関数)の4番目のパラメーターが低すぎると、現時点tolower
では、関数ポインターとしてのみ指定されているため、関数パラメーターの派生型情報が必要です。関数の型を推定することはできません。どのオーバーロードを判別するために使用することはできません。。
3.さまざまな方法で解決できます:
3.1。関数タイプを指定します:
transform( s.begin(), s.end(), s.begin(), (int(*)(int))tolower);
或者
int (*pf)( int ) = tolower; // pf 是一个函数指针,其类型已经明确。
transform( s.begin(), s.end(), s.begin(), pf );
3.2。ラッパー関数を使用する:tolower関数を使用して直接オーバーロードすることによって引き起こされる問題を回避する
int my_tolower( int c )
{
return tolower( c ); // 根据 c 的类型可以确定使用 tolower 的哪个重载函数。
}
// my_tolower 是非模版非重载函数,避免了函数重载带来的类型解析问题。
transform( s.begin(), s.end(), s.begin(), my_tolower );
3.3、グローバルでtolower関数を呼び出す:
非テンプレート関数tolower
は実際には標準Cライブラリ関数から派生しているため、グローバル名前空間std C ++標準ライブラリにも配置されています。std名前空間のtolower関数は関数オーバーロードを形成する可能性があるため、グローバル名前空間には1つのtolower関数しかありません、したがって、グローバル名前空間でtolowerを直接使用することもできます。
transform( s.begin(), s.end(), s.begin(), ::tolower);
総括する:
1.変換テンプレート関数はtolower関数を呼び出し、使用するtolowerオーバーロード関数を決定することができないため、エラーを報告します。
2. ::tolower
競合を回避するためにグローバル関数を呼び出す最も簡単な方法。