2

So I'm pretty new to C++, so I wanted to loop through a multidimensional vector that I have, but I'm getting errors such as

stl_algo.h

error: no match for 'operator==' (operand types are std::vector<std::basic_string<char> >' and 'const std::basic_string<char>'

There is lots of errors, here is the code:

mClass.h

std::vector<std::vector<std::string> > aData;

mClass.cpp

bool mClass::checkVector(std::string k)
{
    if (std::find(mClass::aData.begin(), mClass::aData.end(), k) != mClass::aData.end())
    {
        return true;
    }
    return false;
}
user273324
  • 152
  • 3
  • 12
  • 3
    Thanks for supplying a question complete with error message and source code. The error message says it all: You are trying to compare a vector and a string. – quamrana Jul 14 '14 at 12:48
  • 1
    You can not compare `std::vector` with `std::string` – Mohit Jain Jul 14 '14 at 12:49
  • So how exactly would I loop through it? I assume that is what you mean. Thank you both for your response. EDIT: This is where I got part of that code: http://stackoverflow.com/questions/571394/how-to-find-an-item-in-a-stdvector – user273324 Jul 14 '14 at 12:51
  • Pass string by const reference for performance improvement. – Neil Kirk Jul 14 '14 at 12:58

3 Answers3

7

mClass::aData.begin() and mClass.aData.end() return iterators over vectors, not iterators over strings. There is no operator == to compare a vector and a string. Hence the error.

You'll need to iterate through the vectors. Assuming you have C++11 support:

bool mClass::checkVector(std::string const& k)
{
  for (auto const& vec : aData) { // Each `vec` is a std::vector<std::string>
    for (auto const& str : vec) { // Each `str` is a std::string
      // compare string represented by it2
      if (str == k) {
        return true;
      }
    }
  }
  return false;
}
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
Dan Shield
  • 1,358
  • 7
  • 14
  • 5
    Three remarks: Name 'it' is kind of confusing, as it is not an iterator. Second, it's better to write `for( auto& it : aData )` in this case. Without the '&' the elements are copied. Finally, you should mention that this is a C++11 solution. – thelamb Jul 14 '14 at 12:55
  • That makes sense. Thanks a lot. :-) I will accept as answer when I am able to. – user273324 Jul 14 '14 at 12:55
  • @thelamb - yes, you are correct on both counts. Using `it` is a hard habit to break for me when working with containers. – Dan Shield Jul 14 '14 at 13:16
  • For this I'm getting a few errors. `'auto' changes meaning in C++11; please remove it`, `invalid declaratator before ':' token`, `range-based 'for' loops are not allowed in C++98 mode` – user273324 Jul 17 '14 at 22:52
  • As pointed out in the comments, this solution requires C++11. If you need to enable C++11 for mingw, you can visit [this](http://stackoverflow.com/questions/16136142/c11-functionality-with-mingw) page and see if it applies. Otherwise, you can use any of the other answers which do not require C++11. – Dan Shield Jul 18 '14 at 13:50
1

The (pre-c++11) solution is to iterate through the vectors first:

Note the typedef for convenience.

typedef std::vector<std::vector<std::string> > vvec;
bool mClass::checkVector(std::string k)
{
    for(vvec::const_iterator it=mClass::aData.begin(), end=mClass::aData.end();it!=end;++it){
        const std::vector<std::string>& inner=*it;
        if (std::find(inner.begin(), inner.end(), k) != inner.end())
        {
            return true;
        }
    }
    return false;
}
quamrana
  • 37,849
  • 12
  • 53
  • 71
1

Because you have a multidimensional array you can't use an iterator to go through every value so the best way to do it is to make a loop first

for(std::vector<std::vector<std::string> >::iterator it = Class::aData.begin(); it!=mClass::aData.end(); ++it)
    if (std::find(it->begin(), it->end(), k) != it->end())
    {
        return true;
    }
return false;

You can use std::find only on the lowest level of iterator, not on an iterator on a full vector.

meneldal
  • 1,717
  • 1
  • 21
  • 30