AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 76986701
Accepted
God I Hate Python
God I Hate Python
Asked: 2023-08-27 18:40:35 +0800 CST2023-08-27 18:40:35 +0800 CST 2023-08-27 18:40:35 +0800 CST

std::views::filter do C++20 não filtrando a visualização corretamente

  • 772

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::filterlinha, 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.

c++
  • 2 2 respostas
  • 198 Views

2 respostas

  • Voted
  1. Best Answer
    cpplearner
    2023-08-27T19:02:29+08:002023-08-27T19:02:29+08:00

    std::views::transformrequer que o objeto da função seja regular_invocable, o que significa que chamadas repetidas devem produzir o mesmo valor; caso contrário, o comportamento será indefinido.

    No range-v3 existem views::generatee views::generate_npara 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.

    std::vector<int> values;
    std::ranges::generate_n(std::back_inserter(values), 1005,
        [&taps, &gen] { return std::round(taps(gen)); });
    
    for (const auto& value : values
        | view::filter([](auto val) { return (val < -42 || val > 42); }))
    {
        std::cout << value << ' ';
    }
    
    • 6
  2. 康桓瑋
    2023-08-27T19:26:38+08:002023-08-27T19:26:38+08:00

    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órios

    #include <generator>
    
    std::generator<int> generate(auto gen) {
      for (;;)
        co_yield gen();
    }
    

    então você pode usá-lo como

    auto gen = [] {
      static std::random_device r;
      static std::mt19937 gen(r());
      static std::normal_distribution<float> taps(-4, 15);
      return taps(gen);
    };
    
    for (const auto& value : generate(gen)
        | view::take(1005)
        | view::filter([](auto val) { return (val < -42 || val > 42); }))
    {
       // ...
    }
    

    Demonstração (use a implementação fornecida pelo P2502 )

    • 4

relate perguntas

  • Por que os compiladores perdem a vetorização aqui?

  • Erro de compilação usando CMake com biblioteca [fechada]

  • Erro lançado toda vez que tento executar o premake

  • Como criar um tipo de octeto semelhante a std::byte em C++?

  • Somente operações bit a bit para std::byte em C++ 17?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    destaque o código em HTML usando <font color="#xxx">

    • 2 respostas
  • Marko Smith

    Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}?

    • 1 respostas
  • Marko Smith

    Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)?

    • 2 respostas
  • Marko Smith

    Por que as compreensões de lista criam uma função internamente?

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 respostas
  • Marko Smith

    Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)?

    • 4 respostas
  • Marko Smith

    Por que o construtor de uma variável global não é chamado em uma biblioteca?

    • 1 respostas
  • Marko Smith

    Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto?

    • 1 respostas
  • Marko Smith

    Somente operações bit a bit para std::byte em C++ 17?

    • 1 respostas
  • Martin Hope
    fbrereto Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi Por que as compreensões de lista criam uma função internamente? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A formato fmt %H:%M:%S sem decimais 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python std::views::filter do C++20 não filtrando a visualização corretamente 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa Por que o construtor de uma variável global não é chamado em uma biblioteca? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev Por que os compiladores perdem a vetorização aqui? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan Somente operações bit a bit para std::byte em C++ 17? 2023-08-17 17:13:58 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve