tags:

views:

231

answers:

2

I come across this term "dependent names" typically in the context of templates. However, I rarely touch the latter. Thus naturally would like to know more about the concept of dependent names.

How do you understand it in the context of templates and outside of them? example are critically encouraged!

+4  A: 

A dependent name is essentially a name that depends on a template argument.

When using templates there is a distinction between the point of definition of the template and the point of instantiation i.e. where you actually use the template. Names that depend on a template don't get bound until the point of instantiation whereas names that don't get bound at the point of definition.

A simple example would be:

template< class T > int addInt( T x )
{
    return i + x.toInt();
}

where a declaration or definition of i would need to appear before the definition given above since i does not depend on the template argument T and is therefore bound at the point of definition. The definition of the toInt member of the as-yet-unknown-type x variable only has to appear before the addInt function is actually used somewhere as it is a dependent name ( technically the point of instantiation is taken as the nearest enclosing global or namespace scope just before the point of use and so it has to be available before that ).

Troubadour
I'll just point out that a lot of compilers seem not to enforce the dependent names rule, but that once you break the rule, there can be big variations in what you end up needing to do to make things work. I've had *BIG* issues because of this in the past - bordering on throw-it-out-and-start-again big. Annoying as I *thought* I'd written portable code - and the code concerned had been used in Borland C++ 5 then two (maybe three) versions of MS VC++ before I hit a problem. Basically, beware.
Steve314
I don't think that the 'technically' comment at the end is 100% correct but rather misleading. 'Technically', toInt is a member function of the type of x (argument to addInt), so it must be declared inside that class, that might or not be in the 'nearest global or namespace scope from the point of use': `namespace A { struct B { int toInt(); }; } void f() { A::B b; addInt( b ); }` <- the enclosing namespace at the place of call is the global namespace but the code is correct as th type of the 'b' variable was qualified.
David Rodríguez - dribeas
@dribeas: You're quite correct. I wrote something different to what I was thinking! I've edited the answer to clarify that the enclosing namespace is relevant to the meaning of "point of instantiation" i.e. it happens a bit earlier that the actual point of use. Thanks.
Troubadour
I would still remove the namespace part. The dependent name must be available before the use of the template. In your particular example, with the dependent name being a member function namespaces don't affect, the class can be defined in any other namespace (if the variable definition is qualified). Even if instead of a member you have a free function, ADL would kick in and it will search within the closest namespace to the type of x, not the point of instantiation of the template.
David Rodríguez - dribeas
@dribeas: I don't quite follow now. The namespace part is simply there to point out the subtle difference between the point of instantiation and the point of use i.e if I call `addInt` within a member of some other class then the point of instantiation of `addInt` is not in that class's member at the point of use where you might naturally expect it to be. This is to prevent picking up a binding for dependent names from within that member. Had `toInt` been an ordinary function then any locally defined `toInt` function ( i.e. defined within that member) would be ignored.
Troubadour
+3  A: 
ltcmelo
You should make explicit that 'typename' is required because the dependent name is a type and not a static variable. With dependent names that are not types, 'typename' would not be required.
David Rodríguez - dribeas
Yes, that's one example of a dependent name. Actually, one I see many beginers confused with. I also edited the post with another situation concerning dependent names that I think happen quite often.
ltcmelo
+1: I never realised that the second example was caused by the name being classified as not dependent.
Troubadour