#include <iostream>
#include <vector>
#include <iterator>
#include <boost/concept_check.hpp>
using namespace std;
template<typename InIte, typename Pred>
InIte find_if( InIte s, InIte e, Pred pr )
{
// この関数は、第一/第二引数がInputIteratorであることを要求します。
function_requires< InputIteratorConcept<InIte> >();
// この関数は、第三引数が単項述語であることを要求します。
typedef iterator_traits<InIte>::value_type value_type;
function_requires< UnaryPredicateConcept<Pred, value_type> >();
// find_ifの実装
while( s!=e && !pr(*s) )
++s;
return s;
}
bool is_even( int x ) { return x%2 == 0; }
int main()
{
// 10以上20未満の偶数を探したいつもりのコードなのだけど、
// find_ifはそうやって使うものではないので…
cout << find_if( 10, 20, is_even ) << endl;
// vectorに5が入っているかどうか探したい。
// そんな時はfind_ifじゃなくてfindを使うべき…
vector<int> v;
// ...(略)...
if( v.end() != find_if( v.begin(), v.end(), 5 ) )
// ...(略)...
return 0;
}
test.cpp: エラー E2062 boost/concept_check.hpp 505: 無効な間接参照(関数 TrivialIteratorConcept<int>::constraints() ) エラー E2314 concept_check.hpp 407: 関数でないものを呼び出している (関数 UnaryPredicateConcept<int,int>::constraints() )
別にconcept_checkを使わなくてもエラーになってはくれるのですが、 一般にはやたらと長くて謎のエラーメッセージになってしまって、 何がまずいのかちょっと見にはわかりません。上の例なら、 「int 型が TrivialIterator としての constraints(制約条件) に引っかかるんだな」とかと見て取れます。
関数内の他に、クラステンプレート内でのチェックも行えます。 どんなconceptをどこでチェックできるかについては本家の リファレンス をご覧下さい。自分で新しく別のConceptクラスを定義して用いることも、 勿論可能です。
template<class T> class X {
BOOST_CLASS_REQUIRES2( T, Clonable, IsDerivedFromConcept );
...
};
と使うConceptなどは、書けば実際に使える場面があるかも。