2008-08-19

Concept : Associated typeの不思議さ

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.