例えば次のコードで、
template < typename T >
void g( T x ) { }
template < typename T > requires Foo< T >
void f( T x )
{
g( x ) ;
}
コンセプトFooを記述したいとする。次のように書くのは誤りである。
auto concept Foo < typename T >
{
requires std::CopyConstructible< T > ;
}
なぜならば、この型を引数として、関数gを呼んでいるからだ。当然、関数gもコンセプトで要求しなければならない。
auto concept Foo < typename T >
{
requires std::CopyConstructible< T > ;
void g( T ) ;
}
さて、この時点でもう厳格すぎて嫌になる人間と、そうでない変態がいる。そういう変態は、今は主にBoost界隈に生息しているが、いずれC++0xに移住してくるだろう。そのような変態のためには、続きがある。もし、関数fが次のようであったならば、どのようにコンセプトFooを記述すればよいのだろうか。
template < typename T > requires Foo< T >
void f( T x )
{
std::cout << x << std::endl ;
}
このコンセプトを苦もなく書けるならば、真の変態と自称してよい。答えは次のとおり。
auto concept Foo < typename T >
{
requires std::CopyConstructible< T > ;
std::ostream & operator << ( std::ostream &, T & ) ;
}
なお、このコードに対するConceptGCCのエラーがひどく読みづらい。まだ改善の余地ありだ。VC++のように、typedefされた型名で出力すれば、少しはマシになるのだが。
No comments:
Post a Comment