Funtores de Operador Transparentes


Visual Studio 2013 Preview admite una función de C++14 llamada (de acuerdo con esta página) "Functors de operador transparente". No tengo claro lo que eso significa. La propuesta de C++14 más cercana que encontré es esta, pero no estoy seguro de si es lo mismo: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3421

Estoy buscando una explicación más clara de lo que es, por qué es una mejora, y tal vez un fragmento que demuestre su uso.

Author: GravityWell, 2013-07-19

1 answers

La propuesta de funtores operador transparente está ahí como una forma de tener funtores generalizados que se encuentran en <functional>. Personalmente, creo que la propuesta en sí tiene un buen ejemplo que ayudaría a ilustrar la necesidad de la misma. Sin embargo, voy a seguir adelante y tratar de explicarlo también.

Supongamos que usted tiene una función, una función muy básica mente usted:

template<typename T, typename U>
auto less_than(T&& t, U&& u) -> decltype(std::forward<T>(t) < std::forward<U>(u)) {
    return std::forward<T>(t) < std::forward<U>(u);
}

Sin embargo, desea usar esta función generalizada en el encabezado <algorithm>. Usted tiene dos opciones, para que sea un functor de la estructura:

struct MyLessThanFunctor {
    template<typename T, typename U>
    auto operator()(T&& t, U&& u) -> decltype(std::forward<T>(t) < std::forward<U>(u)){
        return std::forward<T>(t) < std::forward<U>(u);
    }
};

O en C++14, para hacer una lambda polimórfica:

[](auto&& t, auto&& u) -> decltype(auto) { 
    return std::forward<decltype(t)>(t) < std::forward<decltype(u)>(u); 
}

Ambos son muy detallados cuando se usan en un algoritmo como este:

int main() {
    std::vector<int> v = {112,12,1281271,1919101,29181,412,1 };
    std::sort(std::begin(v), std::end(v), MyLessThanFunctor()); // one
    std::sort(std::begin(v), std::end(v), [](auto&& t, auto&& u) -> decltype(auto) { 
        return std::forward<decltype(t)>(t) < std::forward<decltype(u)>(u); 
    });
}

Esta propuesta pretende hacerla más compacta y generalizada haciendo lo siguiente:

std::sort(std::begin(v), std::end(v), std::less<>());

Esto le proporciona un reenvío perfecto y resuelve problemas con truncamiento o problemas que surgen al cambiar el contenedor, pero no el tipo subyacente designado por el contenedor como se menciona en el documento.

Supongamos que usted tiene un funtor no generalizado:

struct Functor {
    bool operator()(uint32_t a, uint32_t b) {
        return a < b;
    }
};

Y lo usas con tu std::vector<uint32_t> y funciona todo bien, pero te olvidas de que tu funtor no está generalizado y lo usas con tu std::vector<uint64_t>. ¿Puedes ver el problema que ha surgido? Los elementos serán truncados antes de ser comparados que probablemente no es lo que el usuario quería. Los funtores generalizados resuelven este problema antes de que surjan.

 22
Author: Rapptz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-22 21:57:06