1

I have this simple function to check if a value is in list:

template <class T>
bool IsinList(list<T> l, T x)
{
    for(list<T>::iterator it=list.begin(); it != list.end(); it++)
    {
        if (*it == x)
            return true;
    }
    return false;
}

I used the function in the same .cpp file like this:

if (!IsinList (words, temp))   
    goodwords.push_back(temp);

but I am getting this error :

'std::list' : use of class template requires template argument list

and I cant figure out what the problem is. I checked in previous asked questions and it didn't help. Can you explain to me what am I doing wrong?

sbi
  • 204,536
  • 44
  • 236
  • 426
זאבי כהן
  • 267
  • 6
  • 16

2 Answers2

6

Typo there:

list.begin() / list.end()

should be

l.begin() / l.end()

Your variable is called l, not list.

EDIT:

As Martinho pointed out, this might not be enough. Some compilers will accept this, but since the iterator depends on the template argument, you might need a typename:

typename list<T>::iterator it=list.begin()
Luchian Grigore
  • 236,802
  • 53
  • 428
  • 594
  • @sbi yes, dependent names and all. – Luchian Grigore May 23 '12 at 11:55
  • As noted in the edited post, not necessarily. Some compilers accept dependent names as-is. – Luchian Grigore May 23 '12 at 11:57
  • 1
    Where by "some compilers" we mostly mean "MSVC". The reason is that MSVC doesn't implement two-phase lookup properly, it only does the second phase. To over-simplify a bit, it's in the first phase that the `typename` is needed. So even if your compiler accepts the code without it, you should put it there anyway in case you ever use a different compiler. – Steve Jessop May 23 '12 at 12:14
  • @SteveJessop yup, I was talking about MSVC. I hope the op sees the comments, I can't seem to target him with @. – Luchian Grigore May 23 '12 at 12:18
  • Hmm, RTL text doesn't mesh well with the syntax for addressing comments, I think. I wonder whether this will help: @זאבי כהן – Steve Jessop May 23 '12 at 12:20
2

You made a typo (list vs. l) and did not specify that list<T>::iterator is a typename. Further, you should pass the list and the search argument by reference-to-const. All in all, it should look like this:

template <class T>
bool IsinList(const list<T>& l, const T& x)
{
    typename list<T>::const_iterator first = l.begin(), last = l.end();
    for(; first != last; ++first)
    {
        if (*it == x)
            return true;
    }
    return false;
}

That said, still don't use this. Much better to use std::find instead

if (std::find(words.begin(), words.end(), temp)==words.end())
{
  goodwords.push_back(temp);
}
Michael Wild
  • 21,851
  • 3
  • 36
  • 40
  • @זאבי כהן if you have c++11, you can also use [std::copy_if](http://en.cppreference.com/w/cpp/algorithm/copy) – juanchopanza May 23 '12 at 12:19
  • 1
    @juanchopanza: and if you don't have C++11, you can use `std::remove_copy_if` with the opposite predicate. Just write `IsNotInList` as well as `IsInList`. – Steve Jessop May 23 '12 at 12:23