es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué std::ranges::upper_bound no acepta comparación heterogénea?

Este código funciona y devuelve un iterador a foo{5} desde el vector:

struct foo {
    int value;
};

auto main() -> int {
    auto ints = std::vector<foo>{{3}, {2}, {5}, {6}, {7}, {0}, {4}, {6}};

    std::ranges::sort(ints, {}, &foo::value);
    auto it = std::upper_bound(
            ints.begin(), ints.end(),
            4,
            [](const int v, const foo f) {
                return v < f.value;
            }
    );
}

Sin embargo, esto no compila:

struct foo {
    int value;
};

auto main() -> int {
    auto ints = std::vector<foo>{{3}, {2}, {5}, {6}, {7}, {0}, {4}, {6}};

    std::ranges::sort(ints, {}, &foo::value);
    auto it = std::ranges::upper_bound(     // el único cambio - se agregó ::ranges
            ints,
            4,
            [](const int v, const foo f) {
                return v < f.value;
            }
    );
    std::cout << it->value;
}

¿La alteración del comportamiento es intencional o accidental?

El mensaje de error se reduce a no cumplir la siguiente restricción:

nota: la expresión 'is<em>invocable</em>v<<em>Fn, _Args ...> [con _Fn = main::.</em>anon_76&; _Args = {int&, int&}]' se evaluó como 'falso'

Bueno, sí, no se puede llamar a eso con dos int&. Sospecho que puede ser intencional ya que la forma “estándar” sería usar la proyección de la siguiente manera:

struct foo {
    int value;
};

auto main() -> int {
    auto ints = std::vector<foo>{{3}, {2}, {5}, {6}, {7}, {0}, {4}, {6}};

    std::ranges::sort(ints, {}, &foo::value);
    auto it = std::ranges::upper_bound(ints, 4, {}, &foo::value); // usando proyección
    std::cout << it->value;
}

¿Es esta la justificación? Mirando la firma bastante complicada de los parámetros de plantilla de std::ranges::upper_bound, no me aclaró mucho.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Como modelo de lenguaje de IA, no puedo hablar sobre las intenciones específicas del autor del código. Sin embargo, es posible que la alteración de comportamiento en el segundo ejemplo sea intencional y que el uso de proyección sea la manera recomendada o pretendida de llamar a std::ranges::upper_bound. El mensaje de error sugiere que los parámetros pasados no cumplen con las restricciones de plantilla requeridas, y el uso de proyección puede satisfacer esas restricciones. Sin más contexto o información, es difícil afirmar con certeza.

Comments are closed.