Thread: template functions?

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    32

    template functions?

    Code:
    #include <iostream>
    #include <vector>
    using namespace std;
    template <class Type>
    void print(const vector<Type>& list) {
       typedef vector<Type>::const_iterator Iter;
       for (Iter iter1 = list.begin(); iter1 != list.end(); ++iter1) {
          cout << *iter1 << " ";
       }
       cout << endl;
    }
    
    int main(void) {
       vector<int> nums;
       int i = 0;
       do {
          nums.push_back(i);
       } while (++i != 10);
       print(nums);
       return 0;
    }
    what I got from compiler message is test.cpp:
    In function ‘void print(const std::vector<Type, std::allocator<_CharT> >&)’:
    test.cpp:6: error: too few template-parameter-lists
    test.cpp:7: error: ‘Iter’ was not declared in this scope
    test.cpp:7: error: expected ‘;’ before ‘iter1’
    test.cpp:7: error: ‘iter1’ was not declared in this scope
    what can i resolve it?

    I know it must be my misunderstanding about using template.. I just can't figure out why
    ANy help will be really appreciated!

  2. #2
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Try replacing:
    Code:
       typedef vector<Type>::const_iterator Iter;
    With:
    Code:
       typedef typename vector<Type>::const_iterator Iter;
    I'm not going in the details, in short, the compiler is too stupid (or, really, can't) to realize that "vector<Type>::const_iterator" is a type. Using "typename" the compiler is told that it is. That happens when you use template arguments like that.

  3. #3
    Registered User
    Join Date
    Feb 2010
    Posts
    32
    It Works!! THX

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    One problem is that std::vector has two template parameters, not one. I am not absolutely sure about this, but it may even be possible for it to have more template parameters as a compiler extension. As such, it would be more typical to generalise this to take a range specified by iterators, and thus the template would be parameterised on the iterator type. Alternatively, you can use the container type as the template parameter, and thus the print function template will work for any container that has begin() and end() member functions that return a const_iterator.

    Another problem is that the name vector<Type>::const_iterator does not necessarily refer to a type name. Since Type does not refer to a particular type, const_iterator could theoretically be a member name, and the compiler is supposed to assume as such, unless it is specified as a type name with the typename keyword:
    Code:
    typedef typename vector<Type>::const_iterator Iter;
    Last edited by laserlight; 02-25-2010 at 08:09 AM. Reason: any -> a
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by laserlight View Post
    One problem is that std::vector has two template parameters, not one. I am not absolutely sure about this, but it may even be possible for it to have more template parameters as a compiler extension. As such, it would be more typical to generalise this to take a range specified by iterators, and thus the template would be parameterised on the iterator type. Alternatively, you can use the container type as the template parameter, and thus the print function template will work for any container that has begin() and end() member functions that return a const_iterator.
    That'd be no fun. Then he could just as well use:
    Code:
    copy(nums.begin(), nums.end(), ostream_iterator<int>(cout, " "));
    (not sure what include files are needed... iterator (for ostream_iterator) and algorithm (for copy), I think).

    That basically does the same this function does (forgot to mention this earlier), except that it does not output a newline.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by EVOEx
    That'd be no fun. Then he could just as well use:
    Not really. The name "print" arguably increases abstraction over the more general "copy", and then one removes the boilerplate concerning the use of ostream_iterator.

    Quote Originally Posted by EVOEx
    (not sure what include files are needed... iterator (for ostream_iterator) and algorithm (for copy), I think).
    Yes, and of course <iostream> for std::cout.

    Quote Originally Posted by EVOEx
    That basically does the same this function does (forgot to mention this earlier), except that it does not output a newline.
    With my second option:
    Code:
    template<typename T>
    void print(const T& list)
    {
        using namespace std;
        typedef typename T::value_type value_type;
        copy(list.begin(), list.end(), ostream_iterator<value_type>(cout, " "));
        cout << endl;
    }
    
    // ...
    
    vector<int> nums;
    // ...
    print(nums);
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o I posted stuff, but now it is gone...

    Why is it gone?!

    Soma
    Last edited by phantomotap; 02-25-2010 at 08:18 AM. Reason: Why?

  8. #8
    Registered User
    Join Date
    Feb 2010
    Posts
    32
    Thx to both EVOEx and laserlight give such a good opinion.
    Though I am not familiar with generic algorithm.. I'll learn it ASAP.
    However,
    I tried again as following..
    Code:
     50 template <class Type>
     51 void printResult(const Type& array) {
     52
     53    typedef typename Type::iterator Iter;
     54    //Print contents
     55    for (Iter iter1= array.begin(); iter1 != array.end(); ++iter1)
     56       cout << *iter1 << " ";
     57    cout << endl;
    Code:
     79 int main(void) {
     80    vector<int> numList;
     81    int i = 0;
     82    do {
     83       numList.push_back(i);
     84    } while (i++ != 10);
     85    printResult(numList);
    And it didn't work..
    test.cpp: In function ‘void printResult(const Type&) [with Type = std::vector<int, std::allocator<int> >]’:
    test.cpp:85: instantiated from here
    test.cpp:55: error: conversion from ‘__gnu_cxx::__normal_iterator<const int*, std::vector<int, std::allocator<int> > >’ to non-scalar type ‘printResult(const Type&) [with Type = std::vector<int, std::allocator<int> >]::Iter’ requested

    Why didn't the compiler instantianted Type = vector<int> as I want?

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The problem is probably because you are trying to use iterator when you should be using const_iterator.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reference Counting
    By Dae in forum C++ Programming
    Replies: 10
    Last Post: 08-13-2009, 07:34 AM
  2. using Template Functions
    By ashcan1979 in forum C++ Programming
    Replies: 3
    Last Post: 09-20-2006, 12:44 AM
  3. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  4. Friend template functions
    By lyx in forum C++ Programming
    Replies: 4
    Last Post: 10-02-2003, 01:11 PM
  5. Template question
    By grscot in forum C++ Programming
    Replies: 1
    Last Post: 04-29-2003, 03:12 PM