template<class T> class Widget; // uses "class" template<typename T> class Widget; // uses "typename" |
template<typename C> // print 2nd element in void print2nd(const C& container) // container; { // this is not valid C++! if (container.size() >= 2) { C::const_iterator iter(container.begin()); // get iterator to 1st element ++iter; // move iter to 2nd element int value = *iter; // copy that element to an int std::cout << value; // print the int } } |
template<typename C> void print2nd(const C& container) { C::const_iterator * x; ... } |
template<typename C> void print2nd(const C& container) { if (container.size() >= 2) { C::const_iterator iter(container.begin()); // this name is assumed to ... // not be a type |
template<typename C> // this is valid C++ void print2nd(const C& container) { if (container.size() >= 2) { typename C::const_iterator iter(container.begin()); ... } } |
template<typename C> // typename allowed (as is "class") void f(const C& container, // typename not allowed typename C::iterator iter); // typename required |
template<typename T> class Derived: public Base<T>::Nested { // base class list: typename not public: // allowed explicit Derived(int x) : Base<T>::Nested(x) // base class identifier in mem { // init. list: typename not allowed typename Base<T>::Nested temp; // use of nested dependent type ... // name not in a base class list or } // as a base class identifier in a ... // mem. init. list: typename required }; |
template<typename IterT> void workWithIterator(IterT iter) { typename std::iterator_traits<IterT>::value_type temp(*iter); ... } |
template<typename IterT> void workWithIterator(IterT iter) { typedef typename std::iterator_traits<IterT>::value_type value_type; value_type temp(*iter); ... } |