Try this: (Updated to match updated question)
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::vector<std::string> myVector = {"cat","bye","what's up?"};
std::string subString = "at";
//Create a lambda function to check if a string contains subString
//Uses s.find(subString), which returns the position of subString in s,
// and checks that it doesn't equal the end of the string
auto containsSubString = [subString](std::string s){
return s.find(subString) != std::string::npos;};
auto iter = std::find_if(myVector.begin(),
myVector.end(),
containsSubString);
//Use a while loop, checking whether iter is at the end of myVector
//Do a find_if starting at the item after iter, std::next(iter)
while (iter != myVector.end())
{
std::cout << *iter << std::endl;
iter = std::find_if(std::next(iter),
myVector.end(),
containsSubString);
}
return 0;
}
Expected Output:
cat
what's up?
Issues with your code:
- Your lambda simply compared
subSequence
to subSequence
, so it always returned true.
- You were using
std::find_if
correctly, but the trick is to just stick it into a while
loop that checks whether you've hit the end of the vector yet.
- While it doesn't hurt to include
-> bool
in your lambda, it's not strictly necessary, because the compiler can infer that information from the lambda's definition (s.find(subString) != std::string::npos
will always return a bool). You only have to explicitly mention type when it might be ambiguous to the compiler (or if you want to make it extra clear to other programmers who might read your code).
Edit: As seen in @Yakk 's answer, it is actually better to use std::next(iter)
instead of iter + 1
, as I originally had it.
This is because std::next(iter)
will work for all types of C++ STL containers, whereas just incrementing the iterator does not work on all containers (though it does work on the most common, such as std::array
or std::vector
).