associated typeは実に不思議だ。大抵は関数の戻り値の型を表すのに使われる。(14.9.1.2.2)。どうも、ネストされた型として使えるようだ。
auto concept Foo < typename T >
{
requires std::CopyConstructible< T > ;
typename type ;
type T::func() ;
}
template < typename T > requires Foo< T >
void f( T x )
{
x.func() ;
// T::typeが使える。
std::cout << typeid(typename T::type).name() << std::endl ;
}
struct Bar
{
Bar func(){ return Bar() ; }
} ;
int main()
{
f(Bar()) ;
}
しかし、以下のコードはコンパイルできない。
auto concept Foo < typename T >
{
requires std::CopyConstructible< T > ;
typename type ;
}
template < typename T > requires Foo< T >
void f( T x )
{
std::cout << typeid(typename T::type).name() << std::endl ;
}
struct Bar
{
typedef Bar type ;
} ;
int main()
{
f(Bar()) ;
}
もし、associated typeで、テンプレートパラメーターのネストされた同名の型を使いたい場合は、default valueを使うことで実現できる。
auto concept Foo < typename T >
{
requires std::CopyConstructible< T > ;
typename type = T::type ;
}
なお、concept_mapで別名を割り当てることも可能だ。例えば、Bar::typeではなく、Bar::typoだったとしても、concept_mapを使えば、ご覧の通り。
struct Bar
{
typedef Bar typo ;// おおっと!
} ;
concept_map Foo< Bar >
{
typedef Bar::typo type ;// おkおk
}
そういえば、今までクラス内部でネストされたtypedefをなんと言うのか分からず、いろんな表現を使っていたが、規格用語としては、Nested type names(9.9)というらしい。そのまんまだ。
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.