C ++ Apaga elementos de contêineres por índices

O problema

Você tem um contêiner C ++ (construído em array, vetor, lista … todos menos os associativos) e deseja remover alguns elementos dele. OK até agora, apenas os elementos a serem removidos são referenciados pelo índice. Como isso pode ser feito ?
</p>

Uma solução

Pode-se conceber uma solução bastante elegante que generaliza não apenas sobre o tipo de recipiente a ser manuseado, mas também sobre o tipo de recipiente que contém os índices a serem removidos, como mostrado abaixo.
</p>

template<typename Cont, typename It>
auto ToggleIndices(Cont &cont, It beg, It end) -> decltype(std::end(cont))
{
int helpIndx(0);
return std::stable_partition(std::begin(cont), std::end(cont),
[&](decltype(*std::begin(cont)) const& val) -> bool {
return std::find(beg, end, helpIndx++) == end;
});
}

Exemplo

</p>

de v apaga todos os índices contidos em ar
</p>

std::vector<int> v;
v
.push_back(0);
v
.push_back(1);
v
.push_back(2);
v
.push_back(3);
v
.push_back(4);
v
.push_back(5);

int ar[] = { 2, 0, 4 };
v
.erase(ToggleIndices(v, std::begin(ar), std::end(ar)), v.end());

Discussão

1. É claro que o algoritmo deve ser incluído.
</p>

2. partição estável foi escolhida para preservar a ordem relativa nos elementos restantes. O std :: partition mais rápido também pode ser usado se a ordem não for importante. Se não formos incomodados em usar a função para ‘manter apenas’ os elementos indexados, então std :: remove if pode ser usado em vez de partição std :: stable (O (n) vs O (nlong (n))
</ p >

3. Se “ar” estivesse contendo os índices a serem mantidos, poderíamos usar nossa função como: v.erase (v.begin (), ToggleIndices (v, std :: begin (ar), std :: end (ar)) );
</p>

4. Um objeto de função pode ser usado em vez do lambda
</p>