Eu estava escrevendo um programa C++ simples que gera uma lista de valores inteiros aleatórios de uma distribuição normal, depois pega os primeiros N itens gerados e os filtra para que seu valor absoluto seja maior que 42. O código que escrevi é o seguinte:
int main() {
//convenience
namespace rng = std::ranges;
namespace view = std::views;
//random generation boilerplate
std::random_device r;
std::mt19937 gen(r());
std::normal_distribution<float> taps(-4, 15);
//the filtering
for (const auto& value : view::repeat(0)
| view::transform([&taps, &gen](auto _) { return std::round(taps(gen)); })
| view::take(1005)
| view::filter([](auto val) { return (val < -42 || val > 42); }))
{
std::cout << value << ' ';
}
return 0;
}
se eu remover a view::filter
linha, a sequência parece perfeitamente normal e há cerca de 3 valores que satisfazem a condição. No entanto, quando o filtro é aplicado, a saída parece ser algum lixo aleatório, como -12 -8 -14 2 -4 -11 -38
. Como isso faz algum sentido? Esses números nem sequer satisfazem a condição de filtragem. Qualquer ajuda é apreciada.
notas:
compilado com g++ -o test main.cpp -std=c++2b
, tanto no Windows quanto no Linux.
Se eu substituir views::repeat(0) por views::iota(0) e compilar com -std=c++20
, a saída será a mesma - algum lixo aleatório.
Além disso, se alguém sugerir a melhor maneira de gerar uma lista a partir do lambda, eu agradeceria muito.
std::views::transform
requer que o objeto da função sejaregular_invocable
, o que significa que chamadas repetidas devem produzir o mesmo valor; caso contrário, o comportamento será indefinido.No range-v3 existem
views::generate
eviews::generate_n
para gerar uma sequência a partir de chamadas de função repetidas, mas (ainda) não está incluído na biblioteca padrão.Por enquanto, pode ser mais fácil usar um algoritmo não preguiçoso.
Como complemento à resposta, em C++23 você pode facilmente construir uma visualização de gerador de números aleatórios usando
std::generator
, o que elimina a necessidade de um contêiner extra para armazenar números aleatóriosentão você pode usá-lo como
Demonstração (use a implementação fornecida pelo P2502 )