• # extern "C", pointer to member function,

    Posté par (site web personnel) . En réponse au journal Conversion entre pointeurs de fonctions incompatibles. Évalué à 3.

    Une autre source de undefined behaviour est quand on a des pointeur extern "C"

    Par exemple:

    extern "C" int my_function(int); // Une fonction d'une bibliothèque C
    int foo() {
     int (*f)(int) = my_function; // Compile sans warnings
     f(42); // undefined behaviour
     // undefined behaviour dans function_cast::operator()
     return apply(my_function);
    }

    Il serrait bien aussi de trouver une solution qui pour créé une fonction générique qui fonctionne avec les pointer vers des fonction membre.

    struct Struct {
     int foo(int) const;
    };
    template<typename T> int my_apply(int(T::*f)(int)) {
     return (T().*f)(42);
    }
    int call_with_foo() {
     //my_apply(&Struct::foo); // ah zut, ça compile pas, à cause du const
     // Je peux essayer avec un cast, mais alors "undefined behavior"
     return my_apply(reinterpret_cast<int(Struct::*)(int)>(&Struct::foo)); 
    };

    Il faut que je fasse un overload pour my_apply(int(T::*f)(int) const).

    Mais si je quelqu'un veut passer une fonction volatile ? Ah oui, il faut rajouter my_apply(int(T::*f)(int) volatile) et my_apply(int(T::*f)(int) const volatile)

    Bon, en C++98 c'est bon, mais en C++11 il faut aussi considérer les "Ref-qualifiers".
    Rajoutons donc des overload. my_apply(int(T::*f)(int) const&) et my_apply(int(T::*f)(int) &&). Je vais passer tous les équivalent avec volatile car bon, qui utilise volatile? mais je rajoute quand même my_apply(int(T::*f)(int) const&&) pour être sur.

    Et quand on crois que on a fini, C++17 fait un changement incompatible et le code code ne compile plus si quelqu'un passe une fonction noexcept alors il faut que je dédouble le tout.

    Au final je dois écrire 4 * 3 * 2 = 24 overloads.