2010-12-29 8 views
7

次のコードはコンパイルされません。コンパイラは、for_each *への呼び出しで*一致する関数がないと不平を言う。なぜこれはそうですか?関数内で定義された構造体をstd :: 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()); 
} 

私は機能flip_allstruct FlipFunctorを移動すると、コードがコンパイルされます。

完全なエラーメッセージ:

no matching function for call to ‘for_each(std::_Rb_tree_iterator<std::pair<Element* const, Element*> >, std::_Rb_tree_iterator<std::pair<Element* const, Element*> >, flip_all(std::map<Element*, Element*, std::less<Element*>, std::allocator<std::pair<Element* const, Element*> > >)::FlipFunctor)’

答えて

13

std::for_eachは関数テンプレートです。テンプレートパラメータの1つは、関数の引数の型です。

テンプレート引数としてローカルタイプを使用することはできません。現在のところ、この言語には制限があります。今後のC++、C++ 0xのリビジョンでは、この制限は削除されているので、ローカル型をテンプレート引数として使用できます。

Visual C++ 2010では、既にテンプレート引数としてローカルクラスの使用がサポートされています。他のコンパイラでのサポートはさまざまです。私は、C++ 0x lambdasをサポートするコンパイラは、テンプレート引数としてローカルクラスの使用もサポートすると考えています(これは完全に真実ではないかもしれませんが、意味をなさないでしょう)。

+2

C++ 03:*ほとんどの場合、使用する場所の近くでアドホックなファンクタを簡単に定義できます。 :-P –

0

私はあなたのコードをコンパイルしようとすると、私は別のエラーが出る:

error: 'flip_all(__gnu_debug_def::map, std::allocator > >)::FlipFunctor' uses local type 'flip_all(__gnu_debug_def::map, std::allocator > >)::FlipFunctor'

実際に予想されることだ、などあなたとしての機能地元のタイプ(ためにここのFlipFunctor)には内部リンケージがあり、テンプレートタイプには外部リンケージが必要です。 std :: for_each の3番目のパラメータはテンプレートであるなので、関数のローカル型の何かをテンプレートに渡すことはできません。

+2

ローカルクラスには内部リンケージはありません。彼らはリンケージを持っていません。 –

+0

エラーメッセージは私よりはるかに優れています。これはgcc 4.5ですか? – Oswald

+0

@Oswald:それはMac OS X上のGCC 4.0ではありません。 –

関連する問題