10155


Boost.Proto Users' Guide を読んでいるのですが、そのなかの

[code]

    typedef typename Context::template eval<Expr>::result_type type;
    
[/code]

という構文の意味が理解できずにいます。  
<http://www.boost.org/doc/libs/1_57_0/doc/html/proto/users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.proto_eval>

C++ の typedef の引数は２つであると思っていたのですが、３つの場合がありうるのでしょうか？

そうであるなら、どのような意味を持つのでしょうか？  
あるいは、typedefの引数は２つの場合しかないならば、上記構文の typename Context::template
はどのような意味を持つと解釈すれば良いのでしょうか？

恥ずかしながら、typedef
の使い方にをひととりおさらいしたつもりなのですが、上記構文の意味はわかりません。ヒントやtypedefについての解説へのURLだけでも助かりますので、どうか宜しくお願いいたします。


CC BY-SA 3.0
2015-05-14T03:23:47.310
10152
2015-05-14T04:04:58.387
9723
question
c++
3つの引数をもつ C++ typedef の意味


一見４つに見えますが、中のうちのひとつは`修飾つき識別子`であり型表記の一部です。  
typedef で型の別名をつけているわけですが  
既にある元の型名 `Context::template evel<Expr>::result_type`  
新しくつける別名 `type`  
なので typedef の引数はやはり２つです。

`Context::template` というのは 入れ子名前指定子 という奴です。  
ISO/IEC 14882:1998 JIS X 3014:2003 5.1 - 7  
後続の識別子 `eval<Expr>::result_type` の検索を `Context` クラス名の中に限定します。  
`result_type` が型であることを明記する必要があるので `typename` が必要です。

[code]

    typedef struct mystruct value_type;
    
[/code]

を typedef に引数３つって言わないのと同じです。


CC BY-SA 3.0
2015-05-14T03:52:47.187
10154
2015-05-14T03:52:47.187
8589
10152
answer


俗に「template限定子」と呼ばれる構文が使われており、そのせいでトークンが分割されてみえています。  
ここでは`typename Context::template eval<Expr>::result_type`型に`type`という別名を宣言しています。

[code]

    typedef typename Context::template eval<Expr>::result_type type;
    
[/code]

（余談ですが、typedefの引数という表現はあまり正確じゃない気はします。意味は通じますけど。）

* * *

C++11言語仕様では [temp.names]/p4 に記載があります。

> When the name of a member template specialization appears after `.` or `->`
> in a postfix-expression or after a nested-name-specifier in a qualified-id,
> and the object expression of the postfix-expression is type-dependent or the
> nested-name-specifier in the qualified-id refers to a dependent type, but
> **the name is not a member of the current instantiation (14.6.2.1), the
> member template name must be prefixed by the keyword`template`.** Otherwise
> the name is assumed to name a non-template. [ Example:
[code]

>     struct X {
>       template<std::size_t> X* alloc();
>       template<std::size_t> static X* adjust();
>     };
>     template<class T> void f(T* p) {
>       T* p1 = p->alloc<200>();          // ill-formed: < means less than
>       T* p2 = p->template alloc<200>(); // OK: < starts template argument
> list
>       T::adjust<100>();          // ill-formed: < means less than
>       T::template adjust<100>(); // OK: < starts template argument list
>     }
>  
[/code]

>
> -- end example ]


CC BY-SA 3.0
2015-05-14T03:53:14.443
10155
2015-05-14T04:04:58.387
2015-05-14T04:04:58.387
49
49
10152
answer