例えば次のコードで、
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
You can use some HTML elements, such as <b>, <i>, <a>, also, some characters need to be entity referenced such as <, > and & Your comment may need to be confirmed by blog author. Your comment will be published under GFDL 1.3 or later license with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.