50

なぜローカルに定義されたクラスを STL アルゴリズムの述語として使用できないのか、私はずっと疑問に思っていました。

質問: Approaching STL algorithms, lambda, local classes and other approachで、BubbaT は「C++ 標準ではローカル型を引数として使用することを禁止しているため」と述べています。

コード例:

int main() {
   int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
   std::vector<int> v( array, array+10 );

   struct even : public std::unary_function<int,bool>
   {
      bool operator()( int x ) { return !( x % 2 ); }
   };
   std::remove_if( v.begin(), v.end(), even() ); // error
}

標準のどこに制限があるか知っている人はいますか? ローカル型を許可しない理由は何ですか?


EDIT : C++11 以降、ローカル型をテンプレート引数として使用することは合法です。

4

2 に答える 2

53

C++98/03 標準では明示的に禁止されています。

C++11 はその制限を取り除きます。

より完全にするために:

テンプレート パラメーターとして使用される型の制限は、C++03 (および C++98) 標準の記事 14.3.1 にリストされています。

ローカル型、リンケージのない型、名前のない型、またはこれらの型のいずれかを組み合わせた型は、テンプレート型パラメーターのテンプレート引数として使用してはなりません。

template <class T> class Y { /* ... */  }; 
void func() {   
      struct S { /* ... */ }; //local class   
      Y< S > y1; // error: local type used as template-argument  
      Y< S* > y2; // error: pointer to local type used as template-argument }

ソースと詳細: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420

要約すると、制限は間違いであり、標準がより速く進化していれば、より早く修正されていたでしょう...

とはいえ、現在、一般的なコンパイラの最新バージョンのほとんどは、ラムダ式を提供するだけでなく、それを許可しています。

于 2009-04-12T23:15:14.007 に答える
5

この制限は '0x で解除されますが、あまり使用されないと思います。それは、C++-0x がラムダを持つためです! :)

int main() {
   int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
   std::vector<int> v( array, array+10 );

   std::remove_if( v.begin()
                 , v.end()
                 , [] (int x) -> bool { return !(x%2); })
}

上記の構文は完全ではないかもしれませんが、一般的な考え方はそこにあります。

于 2009-04-14T10:46:46.020 に答える