関数内で定義された構造体をSTD :: for_eachのファンチャーとして使用できないのはなぜですか?
-
13-10-2019 - |
質問
次のコードはコンパイルされません。コンパイラは、for_each *への呼び出しの一致関数がないと文句を言います。なぜそうなの?
#include <map>
#include <algorithm>
struct Element
{
void flip() {}
};
void flip_all(std::map<Element*, Element*> input)
{
struct FlipFunctor
{
void operator() (std::pair<Element* const, Element*>& item)
{
item.second->flip();
}
};
std::for_each(input.begin(), input.end(), FlipFunctor());
}
私が動くとき struct FlipFunctor
関数の前 flip_all
, 、コードをコンパイルします。
完全なエラーメッセージ:
'for_each(std :: _ rb_tree_iteratorへの呼び出しの一致関数なしu003Cstd::pairu003CElement* const, Element*> >、std :: _ rb_tree_iterator u003Cstd::pairu003CElement* const, Element*> >、flip_all(std :: map u003CElement*, Element*, std::lessu003CElement*> 、std :: allocator u003Cstd::pairu003CElement* const, Element*> >>):: flipfunctor) '
解決
std::for_each
関数テンプレートです。テンプレートパラメーターの1つは、関数引数のタイプです。
ローカルタイプをテンプレート引数として使用することはできません。現在、言語の制限です。 C ++、C ++ 0xの今後の改訂では、この制限が削除されるため、ローカルタイプをテンプレート引数として使用できます。
Visual C ++ 2010は、テンプレートの引数としてローカルクラスの使用をすでにサポートしています。他のコンパイラでのサポートは異なる場合があります。 C ++ 0x lambdasをサポートするコンパイラは、テンプレートの引数としてローカルクラスの使用もサポートすると思います(これは完全に真実ではないかもしれませんが、理にかなっています)。
他のヒント
コードをコンパイルしようとすると、別のエラーが発生します。
エラー: 'flip_all(__ gnu_debug_def :: map、std :: allocator>>):: flipfunctor'はローカルタイプを使用します。
関数のローカルタイプ(ここのFlipFunctorなど)には内部リンクがあり、テンプレートタイプには外部リンケージが必要なため、実際には予想されることです。 std :: for_eachの3番目のパラメーター以降 は テンプレートでは、ローカルタイプの機能を渡すことはできません。