stl: uso de acumulación en C++ con una función constante como parámetro

CorePress2024-01-24  10

No pude encontrar ninguna solución, así que publicaré un tema nuevo. Tengo que usar acumular con una función constante como parámetro (practicando un poco para una prueba):

get_skills(): devuelve una lista de habilidades y se define como:

const vector<string>& get_skills() const;

Tengo que devolver la suma de la duración de todas las habilidades

Lo que he probado:

double sum1 = accumulate(tmpObj.get_skills().begin(), tmpObj.get_skills().end(), 0., [](const string& s, const double& sum){return s.size() + sum;});

y yo y arriba con:

 no matching function for call to object of type lambda
 note: candidate function not viable: no known conversion from 'double' to 'const std::__cxx11::string' (aka 'const basic_string<char>') for 1st argument

¿Alguien podría explicar qué usar como lambda (lo intenté con tmpObj& pero no cambié nada)? y qué está causando la "conversión no conocida de 'doble' a 'const std::__cxx11::string'

¡Gracias de antemano!

Mire la acumulación, especialmente los requisitos previos para la operación BinaryOperation.

- Olaf Dietsche

27/03/2021 a las 11:29

¿No son lo suficientemente claros los ejemplos de la documentación de referencia? ¿Qué te falta en particular allí? Parece que no entendiste algo acerca de cómo debes usar std::accumulate(); no puedes agregar cadenas con dobles.

–πάντα ῥεῖ

27 de marzo, 2021 a las 11:30

@πάνταῥεῖ No pude resolverlo usando la documentación de referencia. Lo que no entiendo es qué debo agregar a []. y también cometí un error tipográfico al usar s.size(). Estoy intentando agregar s.length() a la suma, así que en realidad no estoy agregando una cadena a un doble

-Akastil

27/03/2021 a las 11:35



------------------------------------

Sin jugar con las vistas, puedes transformarlas primero en longitudes de cadena y luegoacumular. Las vistas serían mejores, pero esto es bastante sencillo.

#include <string>
#include <iostream>
#include <numeric>
#include <vector>
#include <algorithm>


int main(int, char**)
{
    std::vector<std::string> skills = { "a", "ab", "abc" };
    std::vector<std::size_t> lengths;

    // transform to string lengths first
    std::transform(
            skills.begin(),
            skills.end(),
            std::back_inserter(lengths),
            [](const std::string& s){ return s.size(); }
    );

    // then accululate
    std::size_t sum = std::accumulate(lengths.begin(), lengths.end(), 0);
    std::cout << "sum = " << sum << '\n';

    return 0;
}

p.d. Debo agregar que si haces esto, también puedes hacerlo manualmente, pero quería dar un ejemplo con aculate según la pregunta.



------------------------------------

Cuando comparas

double sum1 = std::accumulate(tmpObj.get_skills().begin(), tmpObj.get_skills().end(), 0.,
                              [](const string &s, const double &sum)
                                  { return s.size() + sum; });

con std::accumulate - Parámetros

operación - ... Ret fun(const Tipo1 &a, const Tipo2 &b);

y

Tipo 1 - T Tipo2 - iterador

Puedes ver que el primer argumento del operador binario debe corresponder al tipo de retorno (doble, suma), y el segundo operador al tipo de contenedor (std::cadena), por ejemplo

[](double sum, const std::string &s) { return sum + s.size(); }

Esta es también la razón por la que el compilador se queja

no se conoce ninguna conversión de 'doble' a 'const std::__cxx11::string'

No puede convertir la suma, un doble, al primer argumento de la lambda, una cadena.

2

Creo que su firma para [](const string &s, const double &sum) { ... } es incorrecta. ¿Debería ser: [](const double &sum, const string &s) {...}?

- Chris feliz

10 de noviembre de2022 a las 1:34

@ChrisHappy al principio, copié el código palabra por palabra de la pregunta a modo de ilustración. Cuando mires la segunda sección, verás la versión corregida y la explicación de por qué es necesario el cambio.

- Olaf Dietsche

10 de noviembre de 2022 a las 11:33

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare