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
Post a Comment