c++ - When is the "typename" keyword necessary? -


possible duplicate:
officially, typename for?
where , why have put template , typename keywords?

consider code below:

template<class k> class c {     struct p {};     vector<p> vec;     void f(); };  template<class k> void c<k>::f() {     typename vector<p>::iterator p = vec.begin(); } 

why "typename" keyword necessary in example? there other cases "typename" must specified?

short answer: whenever referring nested name dependent name, i.e. nested inside template instance unknown parameter.

long answer: there 3 tiers of entities in c++: values, types, , templates. of can have names, , name alone doesn't tell tier of entity is. rather, information nature of name's entity must inferred context.

whenever inference impossible, have specify it:

template <typename> struct magic; // defined somewhere else  template <typename t> struct {   static const int value = magic<t>::gnarl; // assumed "value"    typedef typename magic<t>::brugh my_type; // decreed "type"   //      ^^^^^^^^    void foo() {     magic<t>::template kwpq<t>(1, 'a', .5); // decreed "template"     //        ^^^^^^^^   } }; 

here names magic<t>::gnarl, magic<t>::brugh , magic<t>::kwpq had expliciated, because impossible tell: since magic template, nature of type magic<t> depends on t -- there may specializations entirely different primary template, example.

what makes magic<t>::gnarl dependent name fact we're inside template definition, t unknown. had used magic<int>, different, since compiler knows (you promise!) full definition of magic<int>.

(if want test yourself, here's sample definition of magic can use. pardon use of constexpr in specializaation brevity; if have old compiler, feel free change static member constant declaration old-style pre-c++11 form.)

template <typename t> struct magic {   static const t                    gnarl;   typedef t &                       brugh;   template <typename s> static void kwpq(int, char, double) { t x; } }; template <> struct magic<signed char> {   // note `gnarl` absent   static constexpr long double brugh = 0.25;  // `brugh` value   template <typename s> static int kwpq(int a, int b) { return + b; } }; 

usage:

int main() {   a<int> a;   a.foo();    return magic<signed char>::kwpq<float>(2, 3);  // no disambiguation here! } 

Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -