Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Petit problème avec std::remove.  (Lu 6481 fois)

0 Membres et 3 Invités sur ce sujet

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Petit problème avec std::remove.
« le: Décembre 25, 2013, 10:54:20 am »
Salut, j'ai essayer de faire la même chose que sur ce tutoriel :
http://fr.sfml-dev.org/forums/index.php?action=post;board=25.0
Mais en utilisant std::remove.

Malheureusement, ça ne marche pas :

#ifndef BINDER_H
#define BINDER_H
#include "sequence.h"
#include "function.h"
struct SLOT {
    template <typename T>
    static Function <typename std::remove_pointer<T>::type> makeSlot (T t) {
        return Function<typename std::remove_pointer<T>::type>(t);
    }
};
#endif // BINDER_H
 

void f (std::string s1, std::string s2) {
    std::cout<<"I'm a function "<<endl;
}
int main () {
     Function<void()> f = SLOT::makeSlot(&f);  
    return 0;
}
 

Il m'indique cette erreur :
main.cpp|30|error: conversion from 'sfgl::Function<sfgl::Function<void()> >' to non-scalar type 'sfgl::Function<void()>' requested|

Est un bu du compilateur ? :o

Pourquoi j'ai un sfgl::Function<sfgl::Function<void()> > d'un côté ???

PS : sinon je voudrais juste essayer de simplifier cette écriture de barbare :

Function<void(std::string, std::string> func = &f
 

Si quelqu'un à une solution je suis preneur. :P
« Modifié: Décembre 25, 2013, 10:56:40 am par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Petit problème avec std::remove.
« Réponse #1 le: Décembre 25, 2013, 11:23:09 am »
Citer
Est un bu du compilateur ?
Oui oui, sûrement...

Sinon essaye de ne pas appeler ta fonction et ta variable avec le même nom, ça pourra aider.

Citer
sinon je voudrais juste essayer de simplifier cette écriture de barbare
C'est pas une écriture de barbare, il faut bien donner le type complet de la fonction que tu veux stocker quelque part. Ca rime à quoi de mettre un f(string, string) dans un Function<void()> ?
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Petit problème avec std::remove.
« Réponse #2 le: Décembre 25, 2013, 11:42:57 am »
Ok, non je voulais juste essayer de faire une classe qui en fonction de l'adresse du pointeur de fonction passé en paramètre, arrive à déterminer le type des arguments de la fonction, mais , en y réfléchissant mieux, je pense pas que ça soit possible.

Tant pis. :P

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Petit problème avec std::remove.
« Réponse #3 le: Décembre 25, 2013, 01:23:13 pm »
Mais si y'a moyen de faire une classe qui permet de stocker un pointeur de fonction quelconque (sans devoir spécifier les types de retour et les types d'argument à la déclaration) alors je suis preneur. *-*

Genre remplacer ça :

Function<void(std::string)> func (&f);
SLOT<Function<void(std::string)>> slot (func);
 

Par ça :
SLOT slot(&f);
 

Mais je pense pas que ça soit possible de le faire en c++.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Messages: 6287
  • Thor Developer
    • Voir le profil
    • Bromeon
Re : Re : Petit problème avec std::remove.
« Réponse #4 le: Décembre 25, 2013, 01:45:46 pm »
Mais je pense pas que ça soit possible de le faire en c++.
Bien sûr c'est possible, mais ça n'a aucun sens. Comment est-ce que tu veux appeler la fonction si tu ne sais pas sa signature? Tu perds toute la sûreté du typage.

Tu poses beaucoup de questions concernant les objets fonctions parce que tu ne comprends pas ces concepts et tu veux faire quelque chose "meilleure". Mais les gens qui ont dévéloppé la bibliothèque standard ont bien réfléchi d'offrir une classe std::function qui est générique, flexible et efficace. Je suis sûr que tu pourrais avancer plus vite si tu investissais du temps pour vraiment comprendre ces idées.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Petit problème avec std::remove.
« Réponse #5 le: Décembre 25, 2013, 02:05:52 pm »
Bah en fait ma classe SIGNAL devrait s'en foutre en fait du typage de la fonction, elle devrait juste se contenter d'appeler la fonction.

Pourtant toi tu as fait pareil avec ta méthode connect dans ta librairie, avec ton callback system, tu passe juste une fonction créée avec bind.

std::bind non plus ne possède des informations sur les types d'arguments d'une fonction.

Et std::fonction non plus car on peut faire ceci (si je ne m'abuse)


std::function<void()> f = (&f, arg1, arg2);
 

Bref j'aimerais juste savoir comment on fait pour pouvoir créer un pointeur de fonction, de cette façon.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Messages: 6287
  • Thor Developer
    • Voir le profil
    • Bromeon
Re : Re : Petit problème avec std::remove.
« Réponse #6 le: Décembre 25, 2013, 02:47:18 pm »
Pourtant toi tu as fait pareil avec ta méthode connect dans ta librairie, avec ton callback system, tu passe juste une fonction créée avec bind.
Non, regarde la declaration de connect():
Connection connect(const EventId& trigger, std::function<void(const Event&)> unaryListener);

Il y a une signature void(const Event&), la méthode connect() n'accepte pas n'importe quel fonction.

Bref j'aimerais juste savoir comment on fait pour pouvoir créer un pointeur de fonction, de cette façon.
Pourquoi? std::function offre déjà tout ce qu'il faut. Tu ne vas pas l'améliorer avec ton implementation...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Petit problème avec std::remove.
« Réponse #7 le: Décembre 25, 2013, 02:57:13 pm »
Donc pas moyen de faire comme avec Qt c'est à dire un slot et un signal qui acceptent n'importe quel type de fonction ???

(Car le type auto ne marche pas pour déclarer des variables membre ou bien des paramètres de fonction...)

Y'a pas moyen de faire un truc genre équivalent à ça ?

Slot (auto f) {
     this->function = function;
}
template <typename R, typename ...A> R call (A... args) {
    return  function(args...);
}
 






Nexus

  • SFML Team
  • Hero Member
  • *****
  • Messages: 6287
  • Thor Developer
    • Voir le profil
    • Bromeon
Re : Petit problème avec std::remove.
« Réponse #8 le: Décembre 25, 2013, 03:18:30 pm »
Pourquoi tu n'utilises pas std::function<void()> comme tu as déjà dit plus tôt? Tu peux appeler n'importe quel autre fonction si tu "bindes" les arguments correctement.

C'est ça que je veux dire avec "tu ne comprends pas ces concepts et tu veux faire quelque chose 'meilleure'"... Il faudrait juste lire un tutoriel/la documentation de std::function et tout comprendre. C'est beaucoup plus efficace qu'éxpérimenter toute la journée...
« Modifié: Décembre 25, 2013, 03:26:06 pm par Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Petit problème avec std::remove.
« Réponse #9 le: Décembre 25, 2013, 03:30:59 pm »
Ok, je vois mais j'ai essayer et ça ne marche pas avec les fonctions avec un type de retour :

std::function<R()> f = &f(std::string, std::string)
 


Nexus

  • SFML Team
  • Hero Member
  • *****
  • Messages: 6287
  • Thor Developer
    • Voir le profil
    • Bromeon
Re : Petit problème avec std::remove.
« Réponse #10 le: Décembre 25, 2013, 03:52:42 pm »
Serieusement, lis la documentation ::)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Petit problème avec std::remove.
« Réponse #11 le: Décembre 25, 2013, 04:04:41 pm »
Ok. ^^

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Petit problème avec std::remove.
« Réponse #12 le: Décembre 25, 2013, 05:34:22 pm »
Sinon un tutoriel sur decay, std::forward, etc... ne serait pas de refus, je n'ai jamais rien compris à ce genre de code :
http://stackoverflow.com/questions/14936539/how-stdfunction-works

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Petit problème avec std::remove.
« Réponse #13 le: Décembre 26, 2013, 10:53:58 am »
Bon bah j'ai réussi  recoder std::function  :D

#define FUNCTION

namespace sfgl {

template<typename T> class Function {
    public :
    template <typename R, typename ...A> Function (R(*f)(A...)) {
        typename std::decay<R(A...)>::type function;
    }

    template <typename R, typename ...A> R operator()(A... args)
    {
        return f(args...);
    }
    using function = typename std::decay<T>::type;
};
 

Mais là je ne l'ai fait que pour les fonctions non membres, je vais faire la même chose pour les autres types de fonction, et ensuite ça sera bon. ^^

Pour recoder std::bind ce n'est pas très compliqué non plus :

template <typename R , typename ...A> struct Bind <R(A...)> {
        Bind (R(*f)(A...), A... args) : f(f)  {
            params = std::make_tuple(std::forward<A>(args)...);
        }
        Bind (R(*f)(A...)) : f(f)  {

        }
        template<int ...S>
        R operator ()() {
            return callFunc(typename helper::gens<sizeof...(A)>::type());
        }
        R operator()(A... args) {
            return f(args...);
        }
        template<int ...S>
        R callFunc(helper::seq<S...>)
        {
            return f(std::get<S>(params) ...);
        }
        std::tuple <A...> params;
        Function<R(A...)> f;
    };
 

Et le helper :
namespace sfgl {
namespace helper {
    template<int ...> struct seq {};

    template<int N, int ...S> struct gens : gens<N-1, N-1, S...> {};

    template<int ...S> struct gens<0, S...>{ typedef seq<S...> type; };
}
 

Bon, le code n'est pas encore tout à fait au point car il manque le std::decay pour ma classe bind, mais, en gros c'est ça. (Sans les placeholder du moins, avec les placeholders je ne sais pas trop comment ça fonctionne mais je n'en ai pas besoin)
Je pense que je vais simplement mettre un type à la place des arguments pour les place holders et remplacer  le tuple par les vrais arguments lors de l'appel à l'opérator().

Bref finalement ce n'étais pas si compliqué que ça.
Les codes source que j'ai trouvé sur internet étaient pas bons, pour ça que j'y ai passé des journées. :/ (A part le code source du helper pour ma classe bind)
« Modifié: Décembre 26, 2013, 10:55:38 am par Lolilolight »

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Petit problème avec std::remove.
« Réponse #14 le: Décembre 26, 2013, 04:11:06 pm »
Mwai non j'ai parlé trop vite, std::function<void()> = &f ne marche pas sans passer par std::bind et le code que j'ai posté ci-dessus non plus mais, j'ai trouvé un article intéressant :

http://sites.univ-provence.fr/wcpp/V1/Lecons/L21.pdf

Page 6.

J'essaye de faire la même chose avec des templates, alors j'ai essayer de redéfinir le template, avec un typedef, pour stocker le pointeur de fonction, pas de problème, mais pour appeler la fonction ça ne fonctionne pas :

#ifndef FUNCTION
#define FUNCTION

namespace sfgl {

template<typename T> class Function {
    public :

    template <typename R, typename ...A> Function (R(*f)(A...)) {
         typedef T R(A...);
         this->f = &f;
    }
    template <typename R, typename ...A> R operator() (A... args) {
        return f(args...);
    }
    private :
    T* f;
};
 

Function<void> func (&f);
func("text");
 

D:\Projets\Projets-c++\TestSFGL\main.cpp|39|error: no match for call to '(sfgl::Function<void>) (const char [5])'|

J'ai compris alors que Function::operator() devenait fonction<void>::operator à la compilation mais je ne sais pas comment résoudre ce problème en redéfinissant operator() en Function<T>::operator();


« Modifié: Décembre 26, 2013, 04:13:57 pm par Lolilolight »