Removing non-prime numbers from a vector

I have a simple function that “primes a list” i.e. it returns the passed vector but without all non-primes. Essentially it removes non-primes from the vector and returns the updated vector. But my function just returns the vector without the numbers 0 and 1. Assume the vector is sorted in ascending order(0, 1, 2, 3, … ) The basic structure of my function follows:

#include<vector>
#include<algorithms>
#include "cmath.h"
.
.
.
std::vector<int> prime_list(std::vector<int> foo){
   int limit_counter = 1;
   const int p_limit = sqrt(foo.at(foo.size() - 1));

   for(int w = 0; w < foo.size(); w++){
      if(foo.at(w) <= 1)
         foo.erase(foo.begin() + w);
   }

   for(int i : foo){
      do{
         if(i % limit_counter == 0)
            foo.erase(std::remove(foo.begin(), foo.end(), i), foo.end());
         limit_counter++;
      }
      while(limit_counter < p_limit);
   }
   return foo;
}

Answer

const int p_limit = sqrt(foo.at(foo.size() - 1));

This will initialize the limit once, based on the last element in the list. You have to do that for each element being test for prime.

More importantly, limit_counter should be initialized for each i

Ignoring the problem with iterators, you can fix it with this pseudo code.

std::vector<int> prime_list(std::vector<int> foo) 
{
    foo.erase(std::remove(foo.begin(), foo.end(), 0), foo.end());
    foo.erase(std::remove(foo.begin(), foo.end(), 1), foo.end());
    for (int i : foo) 
    {
        int limit_counter = 1;
        const int p_limit = static_cast<int>(sqrt(i));
        do 
        {
            if (i % limit_counter == 0)
            {
                //undefined behavior, this might destroy the iterator for `i`
                foo.erase(std::remove(foo.begin(), foo.end(), i), foo.end());
            }
            limit_counter++;
        } while (limit_counter < p_limit);
    }
    return foo;
}

For an easier and safer solution, just create a new list and add the primes to it. Or, create a duplicate list primes and go through the loop in foo

std::vector<int> prime_list(std::vector<int> &foo) 
{
    std::vector<int> primes = foo;
    primes.erase(std::remove(primes.begin(), primes.end(), 0), primes.end());
    primes.erase(std::remove(primes.begin(), primes.end(), 1), primes.end());
    for (int n : foo)
        for (int k = 2, limit = static_cast<int>(sqrt(n)); k <= limit; k++)
            if (n % k == 0)
                primes.erase(std::remove(primes.begin(), primes.end(), n), primes.end());
    return primes;
}