Thread: Template function declaration error

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    13

    Template function declaration error

    Hi all,

    I wrote a program to count the number of times an item appears in a list using a sequential search. I had numerous errors and corrected most of them by way of online tutorials, loking up compiler error codes, and textbooks. I still have a few errors that I can't seem to correct, basically something is wrong with the way I'm declaring the functions as templates. Here's the code with the compiler errors.

    Code:
    #include<iostream>
    #include<string>
    #include<list>
    
    using namespace std;
    
    template <typename T>
    int count(const list<string>& aList, const T& item);
    
    template <typename T>
    typename list<T>::iterator seqSearch(typename list<T>::const_iterator first, typename list<T>::const_iterator last, const T& target);
    
    int main() {
        string arr[] = { "the", "boy", "the", "girl", "the", "person", "the man" };
        int arrSize = sizeof(arr) / sizeof(*arr);
        list<string> strList(arr, arr + arrSize);
        list<string>::const_iterator iter = strList.begin();
    
        int wordCount = count(strList, *iter);
        cout << endl << "The number of times 'the' is in the list is: " << wordCount << endl << endl;
    
        return 0;
    }
    
    
    template <typename T>
    int count(const list<string>& aList, const T& item){
    	int itemCount = 0;
    
    	//set iterator to the beginning of the list
    	list<T>::const_iterator iter = aList.begin();
    
    	//make repeated calls to seqSearch until we reach the end
    	while (iter != aList.end()){
    		iter = seqSearch(iter, aList.end(), item);
    			if (iter != aList.end()){
    			
    			//seqSearch will only return an iterator when item is found in the list
    			itemCount++;
    			iter++;
    			}
    
    	}
    	return itemCount;
    }
    
    template <typename T>
    typename list<T>::iterator seqSearch(typename list<T>::const_iterator start, typename list<T>::const_iterator last, const T& target){
    
    	//compare list elements with target until either we arrive
    	//at last or locate target
    	while (start != last && (*start != target))
    		start++;
    
    	//iter either points to target or is last
    	return start;
    }
    Code:
    ------ Build started: Project: chapt6_quest23b, Configuration: Debug Win32 ------
    Compiling...
    seqSearch2.cpp
    c:\documents and settings\welkj01\my documents\visual studio 2005\projects\chapt6_quest23b\chapt6_quest23b\seqsearch2.cpp(56) : error C2664: 'std::list<_Ty>::_Iterator<_Secure_validation>::_Iterator(std::_List_nod<_Ty,_Alloc>::_Node *,const std::list<_Ty> *)' : cannot convert parameter 1 from 'std::list<_Ty>::_Const_iterator<_Secure_validation>' to 'std::_List_nod<_Ty,_Alloc>::_Node *'
            with
            [
                _Ty=std::string,
                _Secure_validation=true,
                _Alloc=std::allocator<std::string>
            ]
            and
            [
                _Ty=std::string,
                _Secure_validation=true
            ]
            and
            [
                _Ty=std::string,
                _Alloc=std::allocator<std::string>
            ]
            No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
            c:\documents and settings\welkj01\my documents\visual studio 2005\projects\chapt6_quest23b\chapt6_quest23b\seqsearch2.cpp(35) : see reference to function template instantiation 'std::list<_Ty>::_Iterator<_Secure_validation> seqSearch<T>(std::list<_Ty>::_Const_iterator<true>,std::list<_Ty>::_Const_iterator<true>,const T &)' being compiled
            with
            [
                _Ty=std::string,
                _Secure_validation=true,
                T=std::basic_string<char,std::char_traits<char>,std::allocator<char>>
            ]
            c:\documents and settings\welkj01\my documents\visual studio 2005\projects\chapt6_quest23b\chapt6_quest23b\seqsearch2.cpp(19) : see reference to function template instantiation 'int count<std::basic_string<_Elem,_Traits,_Ax>>(const std::list<_Ty> &,const T &)' being compiled
            with
            [
                _Elem=char,
                _Traits=std::char_traits<char>,
                _Ax=std::allocator<char>,
                _Ty=std::string,
                T=std::basic_string<char,std::char_traits<char>,std::allocator<char>>
            ]
    Build log was saved at "file://c:\Documents and Settings\welkj01\My Documents\Visual Studio 2005\Projects\chapt6_quest23b\chapt6_quest23b\Debug\BuildLog.htm"
    chapt6_quest23b - 1 error(s), 0 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    Thank you in advance for your time and any help you can provide.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Can I ask why you're even bothering, when std::find() does precisely this already?

    EDIT: I don't mean my comment to sound nasty. I'm seriously wondering whether this is because you CAN'T use std::find() or you simply aren't aware of it.
    Last edited by brewbuck; 06-11-2007 at 07:25 PM.

  3. #3
    Massively Single Player AverageSoftware's Avatar
    Join Date
    May 2007
    Location
    Buffalo, NY
    Posts
    141
    Quote Originally Posted by jaw24 View Post
    Code:
    //set iterator to the beginning of the list
    	typename list<T>::const_iterator iter = aList.begin();
    I see a missing typename there, that might be it.
    There is no greater sign that a computing technology is worthless than the association of the word "solution" with it.

  4. #4
    Registered User
    Join Date
    Apr 2007
    Posts
    13
    Can I ask why you're even bothering, when std::find() does precisely this already?

    EDIT: I don't mean my comment to sound nasty. I'm seriously wondering whether this is because you CAN'T use std::find() or you simply aren't aware of it.
    I didn't take it as nasty. This was part of project that I just handed in. We had to just write the functions, I wanted to test them in a program before I handed it in, where I found out that it didn't work. This whole template function thing is driving me insane. Everytime I make a correction based on info I find on the web I just get more errors, I'm just chasing my tail.

    To AverageSoftware,
    The missing typename didn't help, but thank you for your suggestion.

  5. #5
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    well on line 56, you are returning 'start' which is a list<T>::const_iterator, but the return type of the function is list<T>::iterator. you can't convert from const_iterator to iterator.

    change the return type to const_iterator and you're sweet.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  6. #6
    Registered User
    Join Date
    Apr 2007
    Posts
    13
    Thank you for your replies, here is where it stands now. I am down to one error(at least until I make the next correction).

    Code:
    #include<iostream>
    #include<string>
    #include<list>
    
    using namespace std;
    
    template <typename T>
    int count(const list<string>& aList, const string& item);
    
    template <typename T>
    typename list<T>::iterator seqSearch(typename list<T>::const_iterator first, typename list<T>::const_iterator last, const T& target);
    
    int main() {
        string arr[] = { "the", "boy", "the", "girl", "the", "person", "the man" };
        int arrSize = sizeof(arr) / sizeof(*arr);
        const list<string> strList(arr, arr + arrSize);
        list<string>::const_iterator iter = strList.begin();
    
    	const string wordToCount = "the";
        int wordCount = count(strList, wordToCount);
        cout << endl << "The number of times 'the' is in the list is: " << wordCount << endl << endl;
    
        return 0;
    }
    
    
    template <typename T>
    int count(const list<string>& aList, const string& item){
    	int itemCount = 0;
    
    	//set iterator to the beginning of the list
    	typename list<T>::const_iterator iter = aList.begin();
    
    	//make repeated calls to seqSearch until we reach the end
    	while (iter != aList.end()){
    		iter = seqSearch(iter, aList.end(), item);
    			if (iter != aList.end()){
    			
    			//seqSearch will only return an iterator when item is found in the list
    			itemCount++;
    			iter++;
    			}
    
    	}
    	return itemCount;
    }
    
    template <typename T>
    typename list<T>::const_iterator seqSearch(typename list<T>::const_iterator start, typename list<T>::const_iterator last, const T& target){
    
    	//compare list elements with target until either we arrive
    	//at last or locate target
    	while (start != last && (*start != target))
    		start++;
    
    	//iter either points to target or is last
    	return start;
    }
    and here is the error.

    Code:
    ------ Build started: Project: chapt6_quest23b, Configuration: Debug Win32 ------
    Compiling...
    seqSearch2.cpp
    c:\documents and settings\welkj01\my documents\visual studio 2005\projects\chapt6_quest23b\chapt6_quest23b\seqsearch2.cpp(20) : error C2783: 'int count(const std::list<_Ty> &,const std::string &)' : could not deduce template argument for 'T'
            with
            [
                _Ty=std::string
            ]
            c:\documents and settings\welkj01\my documents\visual studio 2005\projects\chapt6_quest23b\chapt6_quest23b\seqsearch2.cpp(8) : see declaration of 'count'
    Build log was saved at "file://c:\Documents and Settings\welkj01\My Documents\Visual Studio 2005\Projects\chapt6_quest23b\chapt6_quest23b\Debug\BuildLog.htm"
    chapt6_quest23b - 1 error(s), 0 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    I looked up the error code on msdn2.com and found basically no help. Why is it that you must explicitly declare a variable type in some function templates, which seems to be the issue with my program.

  7. #7
    Massively Single Player AverageSoftware's Avatar
    Join Date
    May 2007
    Location
    Buffalo, NY
    Posts
    141
    The problem is that the template type T doesn't appear in the argument list of count. Therefore, the compiler cannot figure out what it is.

    In that case, you need to call count like so:
    Code:
    count<int>(/*args*/);
    This is assuming you want int to replace T, of course.

    Addendum:
    Looking more closely at the code, did you actually want this:
    Code:
    template <typename T>
    int count(const list<T>& aList, const string& item)
    There is no greater sign that a computing technology is worthless than the association of the word "solution" with it.

  8. #8
    Registered User
    Join Date
    Apr 2007
    Posts
    13
    In that case, you need to call count like so:

    Code:
    count<int>(/*args*/);
    Looking more closely at the code, did you actually want this:

    Code:
    template <typename T>
    int count(const list<T>& aList, const string& item)
    I had tried both of those prior to posting to the board, they created more errors. I tried using count as a non-templated function, still more errors. Where I have it now is the least amount of errors I have had.

  9. #9
    Massively Single Player AverageSoftware's Avatar
    Join Date
    May 2007
    Location
    Buffalo, NY
    Posts
    141
    Quote Originally Posted by jaw24 View Post
    I had tried both of those prior to posting to the board, they created more errors. I tried using count as a non-templated function, still more errors. Where I have it now is the least amount of errors I have had.
    Ah, I see now. I just finally took the time to understand what you're doing.

    You want this:

    Code:
    template <typename T>
    int count(const list<T>& aList, const T& item)
    Like you had originally.

    Gosh, aren't templates fun?

    Addendum:
    You also need to update the prototype for seqSearch to return a const_iterator, it doesn't match the actual function.

    With these changes, the code compiles and runs on my system.
    Last edited by AverageSoftware; 06-12-2007 at 06:57 PM.
    There is no greater sign that a computing technology is worthless than the association of the word "solution" with it.

  10. #10
    Registered User
    Join Date
    Apr 2007
    Posts
    13
    Thank you, thank you, thank you!!! Works for me now also. I really appreciate your help.

    edit: Yes, templates are a blast, I think they become more of a hoot when you throw in iterators.
    Last edited by jaw24; 06-12-2007 at 08:48 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Quantum Random Bit Generator
    By shawnt in forum C++ Programming
    Replies: 62
    Last Post: 06-18-2008, 10:17 AM
  2. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. Errors with including winsock 2 lib
    By gamingdl'er in forum C++ Programming
    Replies: 3
    Last Post: 12-05-2005, 08:13 PM
  5. ras.h errors
    By Trent_Easton in forum Windows Programming
    Replies: 8
    Last Post: 07-15-2005, 10:52 PM