|
Prev: virtualand nonvirtual templateness"
Next: a compiler error in template function default argument value
From: cpluslearn on 10 Apr 2008 06:18 I have a basic question about the keyword 'typename'. typename has to be used whenever a name that depends on a template parameter is a type. But in the function foo() below I am using vector<int>::const_iterator without typename. How does this work? How does the compiler know that const_iterator is not a static member? //////////////////////////////////////////////////////////////// using std::vector; template <typename T> void foo(T const& cont, vector<int> vec) { typename T::const_iterator tIter = cont.begin(); //This is OK vector<int>::const_iterator vecIter = vec.begin(); //How does this work without typename typename vector<int>::const_iterator vecTypIter = vec.begin(); //do I really need typename in this case. } int main() { vector<int> v(10, 1); foo(v, v); } /////////////////////////////////////////////////////////////////// Thanks in advance. --dhina -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Jiri Palecek on 10 Apr 2008 10:44 cpluslearn(a)gmail.com wrote: > I have a basic question about the keyword 'typename'. typename has to > be used whenever a name that depends on a template parameter is a > type. But in the function foo() below I am using > vector<int>::const_iterator without typename. How does this work? How > does the compiler know that const_iterator is not a static member? > //////////////////////////////////////////////////////////////// > using std::vector; > > template <typename T> > void foo(T const& cont, vector<int> vec) > { > typename T::const_iterator tIter = cont.begin(); //This is OK > > vector<int>::const_iterator vecIter = vec.begin(); //How does this > work without typename There's no "T" in vector<int>::const_iterator, therefore it is a non-dependent name. The compiler knows it's not a static member by looking at vector<int> and (possibly) instantiating a const_iterator in it. > typename vector<int>::const_iterator vecTypIter = vec.begin(); //do I > really need typename in this case. No. Jiri Palecek -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Alberto Ganesh Barbati on 10 Apr 2008 10:40 cpluslearn(a)gmail.com ha scritto: > I have a basic question about the keyword 'typename'. typename has to > be used whenever a name that depends on a template parameter is a > type. But in the function foo() below I am using > vector<int>::const_iterator without typename. How does this work? How > does the compiler know that const_iterator is not a static member? > //////////////////////////////////////////////////////////////// > using std::vector; > > template <typename T> > void foo(T const& cont, vector<int> vec) > { > typename T::const_iterator tIter = cont.begin(); //This is OK > > vector<int>::const_iterator vecIter = vec.begin(); //How does this > work without typename > typename vector<int>::const_iterator vecTypIter = vec.begin(); //do I > really need typename in this case. > } It works because vector<int>::const_iterator does *not* depend on a template parameter. In this context, the only template parameter is T and there's no T in vector<int>::const_iterator. HTH, Ganesh -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 10 Apr 2008 10:43 On 10 Apr., 23:18, cplusle...(a)gmail.com wrote: > I have a basic question about the keyword 'typename'. typename has to > be used whenever a name that depends on a template parameter is a > type. But in the function foo() below I am using > vector<int>::const_iterator without typename. How does this work? How > does the compiler know that const_iterator is not a static member? > //////////////////////////////////////////////////////////////// > using std::vector; > > template <typename T> > void foo(T const& cont, vector<int> vec) > { > typename T::const_iterator tIter = cont.begin(); //This is OK > > vector<int>::const_iterator vecIter = vec.begin(); //How does this > work without typename You need to use the typename prefix, if a qualified name depends on a template parameter. In the case "vector<int>::const_iterator" this dependency is now "resolved" (it is said, that "vector<int>" is non-dependent), the compiler "knows" the actual type of vector<int>. Therefore it can found out, whether "vector<int>::const_iterator" specifies a type or something else. "typename" used in this context is required for still depending templates, e.g. consider that you had used "vector<T>::const_iterator" inside your function template foo above. Because it is possible - per language - to write a specialization of std::vector for which "vector<T>::const_iterator" does either *not* exist at all or is not a type, the programmer must help the compiler here. > typename vector<int>::const_iterator vecTypIter = vec.begin(); //do I > really need typename in this case. You don't need typename here, because vector<int> is no dependent type. It is allowed to write that in C++03 in a template context, and it will probably be lifted to be allowed outside of a template context in C++0x (for reasons of simplicity for the programmer). HTH & Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: David Pol on 10 Apr 2008 10:44
On 10 abr, 23:18, cplusle...(a)gmail.com wrote: > I have a basic question about the keyword 'typename'. typename has to > be used whenever a name that depends on a template parameter is a > type. But in the function foo() below I am using > vector<int>::const_iterator without typename. How does this work? How > does the compiler know that const_iterator is not a static member? > //////////////////////////////////////////////////////////////// > using std::vector; > > template <typename T> > void foo(T const& cont, vector<int> vec) > { > typename T::const_iterator tIter = cont.begin(); //This is OK > > vector<int>::const_iterator vecIter = vec.begin(); //How does this > work without typename > typename vector<int>::const_iterator vecTypIter = vec.begin(); //do I > really need typename in this case. > > } > > int main() > { > vector<int> v(10, 1); > foo(v, v);} > > /////////////////////////////////////////////////////////////////// > Thanks in advance. > --dhina Hello, You have // ... vector<int>::const_iterator vecIter = vec.begin(); typename vector<int>::const_iterator vecTypIter = vec.begin(); // ... std::vector<int>::const_iterator is _not_ a dependent name (it does not depend on any template parameter; its syntactic role is known at the point of definition of foo), that is why you do not need to use 'typename'. You would need to use 'typename' if you had something like // ... std::vector<T>::const_iterator it; // ... with T being a template parameter (in that case, the syntactic role of std::vector<T>::const_iterator can never be known at the point of definition of the template). Regards, David -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |