cpp-frug / materials

Documentations à partager entre communautés C++ francophones
25 stars 9 forks source link

Nouvelles versions cpp école primaire #10

Open ghost opened 8 years ago

ghost commented 8 years ago
struct times_looper {

    unsigned long long n;

    template<typename F>
    void operator()(F fun) {
        for(int i = 0; i<n; ++i) {
            fun();
        }
    }

};

times_looper operator "" _times(unsigned long long n) {
    return times_looper{n};
}

int main(int argc, char** argv) {
    100_times( []() { std::cout << "Je ne dois pas jeter d'avion en papier en classe" << std::endl; } ) ;
    return 0;
}
ghost commented 8 years ago

Une autre par Gof< :

#include <iostream>

template<typename F>
auto operator *(int N, F fun) -> decltype((void)fun()) {
    for (int i = 0; i < N; ++i)
        fun();
}

int main() {
    100 * []{ std::cout << "Je ne dois pas jeter d'avion en papier en classe !" << std::endl; };
}

Le decltype((void)fun()) est utile pour limiter l'instanciation de operator * uniquement aux typename F qui permettent de déduire le type de (void)fun(). Donc uniquement pour les types appelables (fonctions, lambdas, functors...) et sans paramètre. C'est le principe du SFINAE. Voir aussi le std::is_callable.

ghost commented 8 years ago
#include <iostream>

template<int N>
void loop() {
    std::cout << "Je ne dois pas jeter d'avion en papier en classe !" << std::endl;
    loop<N-1>();
}

template<>
void loop<0>() {
}

int main(int argc, char** argv) {
    loop<100>();
    return 0;
}
ghost commented 8 years ago
#include <iostream>
#include <future>

int n=100;

int main() {
    if(n--) {
        std::cout << "Je ne dois pas jeter d'avion en papier en classe !" << std::endl;
        std::async(main).wait();
    }
    return 0;
}
olibre commented 8 years ago
#include <iostream>

template<int N>
void loop() {
    std::cout << "Je ne dois pas jeter "
        "d'avion en papier en classe" << std::endl;
    if constexpr (N)
        loop<N-1>();
}

int main() {
    loop<99>();
}
ogoffart commented 8 years ago

Le decltype((void)fun()) dans ma solution est utile car ça permet de ne pas surcharger l'operateur * pour tout les types. (Utilisant SFINAE pour que ça ne fonctionne que avec des functions)

ghost commented 8 years ago

Du coup ça ne prends pas les objets fonctions?

olibre commented 8 years ago

@devnewton Cela prend tous les objets fun qui sont valides quand on essaye de les appeler avec fun() donc les fonctions classiques, les lambdas, les functors, les std::function... (j'ai mis à jour ton second commentaire). Le (void) dans decltype((void)fun()) permet de dire au decltype de ne prendre en compte que void (c'est une conversion de type).