CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 20
  1. #1
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Template question...

    This is really stupid. I don't know why I'm getting the below error at the boldened line in my program. I'm using gcc 3.3.

    Thanks in advance.

    list1.hpp
    Code:
    #include <list>
    
    template <typename T>
    void insert_order(list<T> & ordered_list, const T & item)
    {
       list<T>::iterator curr = ordered_list.begin();
       list<T>::iterator end = ordered_list.end();
    
       while((curr != stop) && ((* curr) < item))
       {
          curr++;
       }
    
       orderd_list.insert(curr, item);
    }
    
    template <typename T>
    void remove_duplicates(list<T> & a_list)
    {
       T curr_value;
       list<T>::iterator curr;
       list<T>::iterator p;
    
       curr = a_list.begin();
    
       while(curr != a_list.end())
       {
          curr_value = * curr;
       }
    }
    Errors:
    Code:
    In file included from prg6_3.cpp:6:
    list1.hpp:6: error: parse error before `>' token
    list1.hpp: In function `void insert_order(...)':
    list1.hpp:9: error: parse error before `>' token
    list1.hpp:10: error: parse error before `>' token
    list1.hpp: At global scope:
    list1.hpp:23: error: parse error before `>' token
    list1.hpp: In function `void remove_duplicates(...)':
    list1.hpp:28: error: parse error before `>' token
    list1.hpp:29: error: parse error before `>' token
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  2. #2
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: Template question...

    Do you have this line?

    Code:
    using std::list;

  3. #3
    Join Date
    Jun 2001
    Location
    Switzerland
    Posts
    4,443

    Re: Template question...

    Quote Originally Posted by Kheun
    Do you have this line?

    Code:
    using std::list;
    Ummm...I'd rather explicitely resolve the scope in this case (that is prefix with std:: as needed) because the code above is likely to reside in a header. The 'using' bloats 'list' into the global namespace, which I find rather unpretty.

    @YSG:
    Code:
    ...
    while((curr != stop) && ((* curr) < item))
    ...
    Who is 'stop' ? You mean 'end', don't you?
    Gabriel, CodeGuru moderator

    Forever trusting who we are
    And nothing else matters
    - Metallica

    Learn about the advantages of std::vector.

  4. #4
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Re: Template question...

    Quote Originally Posted by Gabriel Fleseriu
    Ummm...I'd rather explicitely resolve the scope in this case (that is prefix with std:: as needed) because the code above is likely to reside in a header. The 'using' bloats 'list' into the global namespace, which I find rather unpretty.

    @YSG:
    Code:
    ...
    while((curr != stop) && ((* curr) < item))
    ...
    Who is 'stop' ? You mean 'end', don't you?
    Ahh... that's right, thanks dude . I'll just post all of my source files as well as the error output, it should give a better view of what I'm trying to do.

    Errors:
    Code:
    In file included from prg6_3.cpp:6:
    list1.hpp:5: error: parse error before `>' token
    list1.hpp: In function `void insert_order(...)':
    list1.hpp:8: error: parse error before `>' token
    list1.hpp:9: error: parse error before `>' token
    list1.hpp: At global scope:
    list1.hpp:22: error: parse error before `>' token
    list1.hpp: In function `void remove_duplicates(...)':
    list1.hpp:27: error: parse error before `>' token
    list1.hpp:28: error: parse error before `>' token
    In file included from prg6_3.cpp:7:
    util.hpp: At global scope:
    util.hpp:5: error: parse error before `&' token
    util.hpp: In function `void write_list(...)':
    util.hpp:7: error: parse error before `>' token
    prg6_3.cpp: In function `int main()':
    prg6_3.cpp:21: error: no matching function for call to `insert_order(
       std::list<int, std::allocator<int> >&, int&)'
    prg6_3.cpp:26: error: no matching function for call to `write_list(
       std::list<int, std::allocator<int> >&)'
    prg6_3.cpp:29: error: no matching function for call to `remove_duplicates(
       std::list<int, std::allocator<int> >&)'
    prg6_3.cpp:33: error: no matching function for call to `write_list(
       std::list<int, std::allocator<int> >&)'
    Attached Files Attached Files
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  5. #5
    Join Date
    Feb 2002
    Posts
    4,640

    Re: Template question...

    I only looked at list1.hpp. There's no include directive, and no declaration of the class 'list'. The compiler doesn't know what a "list" is, so you get these errors.

    Add '#include <list>' to the top of 'list1.hpp'; and replace all instances of "list" with "std::list". If you are trying to use the STL list, of course. Otherwise, just include your declaration of "list".

    Viggy

  6. #6
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Re: Template question...

    Quote Originally Posted by MrViggy
    I only looked at list1.hpp. There's no include directive, and no declaration of the class 'list'. The compiler doesn't know what a "list" is, so you get these errors.

    Add '#include <list>' to the top of 'list1.hpp'; and replace all instances of "list" with "std::list". If you are trying to use the STL list, of course. Otherwise, just include your declaration of "list".

    Viggy
    Yes, I am trying to use STL.

    Here is what I have for list1.hpp. I did as you instructed, but I still got approximately as many errors.
    Code:
    #include <list>
    
    template <typename T>
    void insert_order(std::list<T> & ordered_list, const T & item)
    {
       std::list<T>::iterator curr = ordered_list.begin();
       std::list<T>::iterator end = ordered_list.end();
    
       while((curr != end) && ((* curr) < item))
       {
          curr++;
       }
    
       orderd_list.insert(curr, item);
    }
    
    template <typename T>
    void remove_duplicates(std::list<T> & a_list)
    {
       T curr_value;
       std::list<T>::iterator curr;
       std::list<T>::iterator p;
    
       curr = a_list.begin();
    
       while(curr != a_list.end())
       {
          curr_value = * curr;
    
          p = curr;
          p++;
    
          while(p != a_list.end())
          {
             if((* p) == curr_value)
    	 {
    	    a_list.erase(p++);
    	 }
    	 else
    	 {
    	    p++;
    	 }
    
    	 curr++;
          }
       }
    }
    Errors:
    Code:
    In file included from prg6_3.cpp:6:
    list1.hpp: In function `void insert_order(std::list<T, std::allocator<_CharT>
       >&, const T&)':
    list1.hpp:10: warning: `std::list<T, std::allocator<_CharT> >::iterator' is
       implicitly a typename
    list1.hpp:10: warning: implicit typename is deprecated, please see the
       documentation for details
    list1.hpp:11: warning: `std::list<T, std::allocator<_CharT> >::iterator' is
       implicitly a typename
    list1.hpp:11: warning: implicit typename is deprecated, please see the
       documentation for details
    list1.hpp: In function `void remove_duplicates(std::list<T,
       std::allocator<_CharT> >&)':
    list1.hpp:29: warning: `std::list<T, std::allocator<_CharT> >::iterator' is
       implicitly a typename
    list1.hpp:29: warning: implicit typename is deprecated, please see the
       documentation for details
    list1.hpp:30: warning: `std::list<T, std::allocator<_CharT> >::iterator' is
       implicitly a typename
    list1.hpp:30: warning: implicit typename is deprecated, please see the
       documentation for details
    In file included from prg6_3.cpp:7:
    util.hpp: At global scope:
    util.hpp:5: error: parse error before `&' token
    util.hpp: In function `void write_list(...)':
    util.hpp:7: error: parse error before `>' token
    prg6_3.cpp: In function `int main()':
    prg6_3.cpp:26: error: no matching function for call to `write_list(
       std::list<int, std::allocator<int> >&)'
    prg6_3.cpp:33: error: no matching function for call to `write_list(
       std::list<int, std::allocator<int> >&)'
    list1.hpp: In function `void insert_order(std::list<T, std::allocator<_CharT>
       >&, const T&) [with T = int]':
    prg6_3.cpp:21:   instantiated from here
    list1.hpp:20: error: `orderd_list' undeclared (first use this function)
    list1.hpp:20: error: (Each undeclared identifier is reported only once for each
       function it appears in.)
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  7. #7
    Join Date
    Sep 2004
    Posts
    519

    Re: Template question...

    When studying the error messages it seems that the only error list1.hpp generated was:

    list1.hpp:20: error: `orderd_list' undeclared (first use this function)
    list1.hpp:20: error: (Each undeclared identifier is reported only once for each
    function it appears in.)
    So:
    Code:
            orderd_list.insert(curr, item);
    Should be:
    Code:
            ordered_list.insert(curr, item);
    You got a handful of warnings though. The other errors seems to be from util.hpp and prg6_3.cpp.

    If you are using STL why not use more of it. For instance, STL already contains algorithms for removing non-unique items (in a sorted container).

    Code:
    // ListTest.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    
    #include <algorithm>
    #include <cstddef>
    #include <cstdlib>
    #include <list>
    namespace
    {
        template<typename T>
        struct find_predicate
        {
            find_predicate(T const & item)
                :   m_item(item)
            {
            }
    
            bool const operator()(T const & item)
            {
                return m_item < item;
            }
    
            T const & m_item;
        };
    
    
        template<typename container_type, typename T>
        void insert_preserve_order(container_type & ordered_list, T const & item)
        {
            typename container_type::iterator const l_insertion_point(
                std::find_if(
                    ordered_list.begin(), 
                    ordered_list.end(), 
                    find_predicate<T>(item)));
    
            if( l_insertion_point != ordered_list.end() )
            {
                ordered_list.insert(l_insertion_point, item);
            }
            else
            {
                ordered_list.push_back(item);
            }       
        }
    
        template <typename container_type>
        void remove_duplicates_from_sorted_container(container_type & ordered_list)
        {
            ordered_list.erase(
                std::unique(ordered_list.begin(), ordered_list.end()),
                ordered_list.end());
        }
        
    }
    
    int main(int, char*)
    {
        std::list<int> l_list;
        l_list.push_back(1);
        l_list.push_back(3);
        l_list.push_back(4);
        l_list.push_back(5);
        l_list.push_back(7);
    
        insert_preserve_order(l_list, 3);
        insert_preserve_order(l_list, 2);
        insert_preserve_order(l_list, 6);
        insert_preserve_order(l_list, 7);
    
        remove_duplicates_from_sorted_container(l_list);
    
        return EXIT_SUCCESS;
    }
    find_predicate is a predicate used to locate the insertion point. std::find_if terminates when the predicate returns true.

    Hope this is of some help.

  8. #8
    Join Date
    Feb 2002
    Posts
    4,640

    Re: Template question...

    Heh, sorry! It looks like util.hpp has the same issues (no include for <list> and no "std::" in front of list).

    As for the warnings, I'm not too sure why they're being issued, except maybe because you are defining a template; and using the template param as the param into another template (the list).

    Oh, don't forget to '#include <iostream>' at the top of util.hpp! It looks like the CPP file is okay (sorry, I didn't have a chance to compile these myself!)

    Viggy

  9. #9
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Re: Template question...

    Quote Originally Posted by MrViggy
    Heh, sorry! It looks like util.hpp has the same issues (no include for <list> and no "std::" in front of list).

    As for the warnings, I'm not too sure why they're being issued, except maybe because you are defining a template; and using the template param as the param into another template (the list).

    Oh, don't forget to '#include <iostream>' at the top of util.hpp! It looks like the CPP file is okay (sorry, I didn't have a chance to compile these myself!)

    Viggy
    That's alright. Unfortunately I don't have enough time at the moment to fix all of the errors, so I'll leave it as is and pick it up on Saturday.
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  10. #10
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Re: Template question...

    Quote Originally Posted by marten_range
    When studying the error messages it seems that the only error list1.hpp generated was:



    So:
    Code:
            orderd_list.insert(curr, item);
    Should be:
    Code:
            ordered_list.insert(curr, item);
    You got a handful of warnings though. The other errors seems to be from util.hpp and prg6_3.cpp.

    If you are using STL why not use more of it. For instance, STL already contains algorithms for removing non-unique items (in a sorted container).

    Code:
    // ListTest.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    
    #include <algorithm>
    #include <cstddef>
    #include <cstdlib>
    #include <list>
    namespace
    {
        template<typename T>
        struct find_predicate
        {
            find_predicate(T const & item)
                :   m_item(item)
            {
            }
    
            bool const operator()(T const & item)
            {
                return m_item < item;
            }
    
            T const & m_item;
        };
    
    
        template<typename container_type, typename T>
        void insert_preserve_order(container_type & ordered_list, T const & item)
        {
            typename container_type::iterator const l_insertion_point(
                std::find_if(
                    ordered_list.begin(), 
                    ordered_list.end(), 
                    find_predicate<T>(item)));
    
            if( l_insertion_point != ordered_list.end() )
            {
                ordered_list.insert(l_insertion_point, item);
            }
            else
            {
                ordered_list.push_back(item);
            }       
        }
    
        template <typename container_type>
        void remove_duplicates_from_sorted_container(container_type & ordered_list)
        {
            ordered_list.erase(
                std::unique(ordered_list.begin(), ordered_list.end()),
                ordered_list.end());
        }
        
    }
    
    int main(int, char*)
    {
        std::list<int> l_list;
        l_list.push_back(1);
        l_list.push_back(3);
        l_list.push_back(4);
        l_list.push_back(5);
        l_list.push_back(7);
    
        insert_preserve_order(l_list, 3);
        insert_preserve_order(l_list, 2);
        insert_preserve_order(l_list, 6);
        insert_preserve_order(l_list, 7);
    
        remove_duplicates_from_sorted_container(l_list);
    
        return EXIT_SUCCESS;
    }
    find_predicate is a predicate used to locate the insertion point. std::find_if terminates when the predicate returns true.

    Hope this is of some help.
    Thanks for your help. This is an exercise that I picked up from a book, so that I can improve my skills.
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  11. #11
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Re: Template question...

    Ok. I managed to fix the errors and it compiled (put the using namespace std; before including the header files), but with oodles of fun warnings. The files are attached.
    Code:
    In file included from prg6_3.cpp:8:
    list1.hpp: In function `void insert_order(std::list<T, std::allocator<_CharT>
       >&, const T&)':
    list1.hpp:8: warning: `std::list<T, std::allocator<_CharT> >::iterator' is
       implicitly a typename
    list1.hpp:8: warning: implicit typename is deprecated, please see the
       documentation for details
    list1.hpp:9: warning: `std::list<T, std::allocator<_CharT> >::iterator' is
       implicitly a typename
    list1.hpp:9: warning: implicit typename is deprecated, please see the
       documentation for details
    list1.hpp: In function `void remove_duplicates(std::list<T,
       std::allocator<_CharT> >&)':
    list1.hpp:27: warning: `std::list<T, std::allocator<_CharT> >::iterator' is
       implicitly a typename
    list1.hpp:27: warning: implicit typename is deprecated, please see the
       documentation for details
    list1.hpp:28: warning: `std::list<T, std::allocator<_CharT> >::iterator' is
       implicitly a typename
    list1.hpp:28: warning: implicit typename is deprecated, please see the
       documentation for details
    In file included from prg6_3.cpp:9:
    util.hpp: In function `void write_list(const std::list<T,
       std::allocator<_CharT> >&, const std::string&)':
    util.hpp:7: warning: `std::list<T, std::allocator<_CharT> >::const_iterator' is
       implicitly a typename
    util.hpp:7: warning: implicit typename is deprecated, please see the
       documentation for details
    Attached Files Attached Files
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  12. #12
    Join Date
    Feb 2004
    Location
    USA - Florida
    Posts
    729

    Re: Template question...

    Simple fix, in list1.hpp, change all the list<T>::iterator or list<T>::const_iterator (in general everywhere you see list<T>::...) to typename list<T>::iterator or typename list<T>::const_iterator (in general, typename list<T>::....).

    Also, good luck fixing the program crash when you're debugging
    Hungarian notation, reinterpreted? http://www.joelonsoftware.com/articles/Wrong.html

  13. #13
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Re: Template question...

    Quote Originally Posted by cma
    Simple fix, in list1.hpp, change all the list<T>::iterator or list<T>::const_iterator (in general everywhere you see list<T>::...) to typename list<T>::iterator or typename list<T>::const_iterator (in general, typename list<T>::....).

    Also, good luck fixing the program crash when you're debugging
    Screw it. I'm giving up on this, it's not worth the head ache. The author of my book continuously uses the same util.h and list1.h header files in some of his examples as the book progresses, it's very annoying.
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  14. #14
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Template question...

    The missing "typename" error is very common. It suddenly appeared on compilers that follow the ANSI C++ spec concerning names within templates.

    YourSurrogateGod, the explanation for your latest errors are simple:
    Code:
    #include <list>
    template <typename T>
    class foo
    {
        std::list<T> list_t;
        std::list<T>::iterator it;  // error, but not on older compilers
    };
    The problem with the second line is fundamental -- the compiler doesn't know if "iterator" is a type, or a static member variable of std::list<T>, so the compiler throws its hands in the air and gives you an error. This makes sense for the compiler to give you an error, since to specify a static member, you use the "::" (scope resolution operator), therefore the ambiguity.

    To tell the compiler that "iterator" is a typename and not a static member of std::list<T>, you use the "typename" qualifier.
    Code:
    #include <list>
    template <typename T>
    class foo
    {
        std::list<T> list_t;
        typename std::list<T>::iterator it;  // OK
    };
    You will come across this again, especially if you use Visual C++ 7.x, Dev-C++/MingW, or any ANSI compliant compiler. The problem with the book is that the syntax of leaving out the "typename" worked for many compilers up until recently. So give the book a chance by fixing this problem. I have had to "fix" many header files when compiling under a newer compiler, just for this error alone.

    There are a few posts on CodeGuru in this forum and in the Visual C++ forum where persons were getting the very same error you're getting, and couldn't understand why. It is one of the toughest errors to figure out if you are not aware of this issue.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; December 11th, 2004 at 08:09 PM.

  15. #15
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Re: Template question...

    Quote Originally Posted by Paul McKenzie
    The missing "typename" error is very common. It suddenly appeared on compilers that follow the ANSI C++ spec concerning names within templates.

    YourSurrogateGod, the explanation for your latest errors are simple:
    Code:
    #include <list>
    template <typename T>
    class foo
    {
        std::list<T> list_t;
        std::list<T>::iterator it;  // error, but not on older compilers
    };
    The problem with the second line is fundamental -- the compiler doesn't know if "iterator" is a type, or a static member variable of std::list<T>, so the compiler throws its hands in the air and gives you an error. This makes sense for the compiler to give you an error, since to specify a static member, you use the "::" (scope resolution operator), therefore the ambiguity.

    To tell the compiler that "iterator" is a typename and not a static member of std::list<T>, you use the "typename" qualifier.
    Code:
    #include <list>
    template <typename T>
    class foo
    {
        std::list<T> list_t;
        typename std::list<T>::iterator it;  // OK
    };
    You will come across this again, especially if you use Visual C++ 7.x, Dev-C++/MingW, or any ANSI compliant compiler. The problem with the book is that the syntax of leaving out the "typename" worked for many compilers up until recently. So give the book a chance by fixing this problem. I have had to "fix" many header files when compiling under a newer compiler, just for this error alone.

    There are a few posts on CodeGuru in this forum and in the Visual C++ forum where persons were getting the very same error you're getting, and couldn't understand why. It is one of the toughest errors to figure out if you are not aware of this issue.

    Regards,

    Paul McKenzie
    Hmm... ok.

    These are the errors that I'm getting. One thing that I think is odd is the fact that it's giving me a parse error right before template .
    Code:
    In file included from prg6_3.cpp:8:
    list1.hpp: In function `void insert_order(std::list<T, std::allocator<_CharT>
       >&, const T&)':
    list1.hpp:13: error: parse error before `template'
    list1.hpp: In function `void remove_duplicates(std::list<T,
       std::allocator<_CharT> >&)':
    list1.hpp:32: error: parse error before `template'
    In file included from prg6_3.cpp:9:
    util.hpp: In function `void write_list(const std::list<T,
       std::allocator<_CharT> >&, const std::string&)':
    util.hpp:12: error: parse error before `template'
    list1.hpp: In function `void insert_order(std::list<T, std::allocator<_CharT>
       >&, const T&) [with T = int]':
    prg6_3.cpp:21:   instantiated from here
    list1.hpp:17: error: `curr' undeclared (first use this function)
    list1.hpp:17: error: (Each undeclared identifier is reported only once for each
       function it appears in.)
    list1.hpp:17: error: `end' undeclared (first use this function)
    util.hpp: In function `void write_list(const std::list<T,
       std::allocator<_CharT> >&, const std::string&) [with T = int]':
    prg6_3.cpp:26:   instantiated from here
    util.hpp:14: error: `iter' undeclared (first use this function)
    list1.hpp: In function `void remove_duplicates(std::list<T,
       std::allocator<_CharT> >&) [with T = int]':
    prg6_3.cpp:29:   instantiated from here
    list1.hpp:45: error: `p' undeclared (first use this function)
    Here is the list1.h file.
    Code:
    #include <iostream>
    #include <list>
    
    using namespace std;
    
    template <typename T>
    void insert_order(list<T> & ordered_list, const T & item)
    {
       template list<T>::iterator curr = ordered_list.begin();
       template list<T>::iterator end = ordered_list.end();
    
       while((curr != end) && ((* curr) < item))
       {
          curr++;
       }
    
       ordered_list.insert(curr, item);
    }
    
    template <typename T>
    void remove_duplicates(list<T> & a_list)
    {
       T curr_value;
       template list<T>::iterator curr;
       template list<T>::iterator p;
    
       curr = a_list.begin();
    
       while(curr != a_list.end())
       {
          curr_value = * curr;
    
          p = curr;
          p++;
    
          while(p != a_list.end())
          {
             if((* p) == curr_value)
    	 {
    	    a_list.erase(p++);
    	 }
    	 else
    	 {
    	    p++;
    	 }
    
    	 curr++;
          }
       }
    }
    util.h
    Code:
    #include <iostream>
    #include <list>
    
    using namespace std;
    
    template <typename T>
    void write_list(const list<T> & alist, const string & separator = "  ")
    {
        template list<T>::const_iterator iter;
    
        for(iter = alist.begin(); iter != alist.end(); iter++)
        {
    	std::cout << * iter << separator;
        }
    
        std::cout << "\n\n";
    }
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured