IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

specialisation des templates variadic


Sujet :

Langage C++

  1. #1
    Membre habitué
    Inscrit en
    Février 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 11
    Par défaut specialisation des templates variadic
    Bonjour,

    Voici un problème avec les templates variadic.
    En fait, voici les functions disponibles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    template< class ClassType >
    		vector< ClassType * > Clone( const vector< ClassType * > &objects ) const;
     
    		template< class ReturnType >
    		shared_ptr< ReturnType > Get( ReturnType * ( PL::ConcreteAssetFactory::*createFunction )() const , shared_ptr<ReturnType> ( PL::AssetFactoryStore::*getFunction )() const , void ( PL::AssetFactoryStore::*setFunction )( shared_ptr<ReturnType> ) ) const;
     
    		template< class ReturnType , typename Argument >
    		shared_ptr< ReturnType > Get( ReturnType * ( PL::ConcreteAssetFactory::*createFunction )( Argument ) const , shared_ptr<ReturnType>( PL::AssetFactoryStore::*getFunction )( Argument ) const , void ( PL::AssetFactoryStore::*setFunction )( Argument , shared_ptr<ReturnType> ) , Argument arg ) const;
     
    		template< class ReturnType , typename Argument1 , typename Argument2 >
    		shared_ptr< ReturnType > Get( ReturnType * ( PL::ConcreteAssetFactory::*createFunction )( Argument1 , Argument2 ) const , shared_ptr<ReturnType>( PL::AssetFactoryStore::*getFunction )( Argument1 , Argument2 ) const , void ( PL::AssetFactoryStore::*setFunction )( Argument1 , Argument2 , shared_ptr<ReturnType> ) , Argument1 arg1 , Argument2 arg2 ) const;
     
    		template< class ReturnType , typename Argument1 , typename Argument2 >
    		shared_ptr< ReturnType > Get( ReturnType * ( PL::ConcreteAssetFactory::*createFunction )( Argument1 , Argument2 , DateFunctionFactory * ) const , shared_ptr<ReturnType>( PL::AssetFactoryStore::*getFunction )( Argument1 , Argument2 ) const , void ( PL::AssetFactoryStore::*setFunction )( Argument1 , Argument2 , shared_ptr<ReturnType> ) , Argument1 arg1 , Argument2 arg2 , DateFunctionFactory *forwards ) const;
     
    		template< class ReturnType , typename Argument1 , typename Argument2 >
    		shared_ptr< ReturnType > Get( ReturnType * ( PL::ConcreteAssetFactory::*createFunction )( Argument1 , Argument2 , DateFunctionFactory * , DatePairFunctionFactory * ) const , shared_ptr<ReturnType>( PL::AssetFactoryStore::*getFunction )( Argument1 , Argument2 ) const , void ( PL::AssetFactoryStore::*setFunction )( Argument1 , Argument2 , shared_ptr<ReturnType> ) , Argument1 arg1 , Argument2 arg2 , DateFunctionFactory *forwards , DatePairFunctionFactory *drifts ) const;
     
    		template< class ReturnType , typename Argument1 , typename Argument2 >
    		shared_ptr< ReturnType > Get2( ReturnType * ( PL::ConcreteAssetFactory::*createFunction )( Argument1 , Argument2 , DateFunctionFactory * , DateFunctionFactory * ) const , shared_ptr<ReturnType>( PL::AssetFactoryStore::*getFunction )( Argument1 , Argument2 ) const , void ( PL::AssetFactoryStore::*setFunction )( Argument1 , Argument2 , shared_ptr<ReturnType> ) , Argument1 arg1 , Argument2 arg2 , DateFunctionFactory *forwards , DateFunctionFactory *forwardsWithoutDD ) const;
     
    		template< class ReturnType , typename Argument1 , typename Argument2 , typename Argument3 >
    		shared_ptr< ReturnType > Get( ReturnType * ( PL::ConcreteAssetFactory::*createFunction )( Argument1 , Argument2 , Argument3 ) const , shared_ptr<ReturnType>( PL::AssetFactoryStore::*getFunction )( Argument1 , Argument2 , Argument3 ) const , void ( PL::AssetFactoryStore::*setFunction )( Argument1 , Argument2 , Argument3 , shared_ptr<ReturnType> ) , Argument1 arg1 , Argument2 arg2 , Argument3 arg3 ) const;
     
    		template< class ReturnType , typename Argument1 , typename Argument2 , typename Argument3 >
    		shared_ptr< ReturnType > Get( ReturnType * ( PL::ConcreteAssetFactory::*createFunction )( Argument1 , Argument2 , Argument3 , DateFunctionFactory * ) const , shared_ptr<ReturnType>( PL::AssetFactoryStore::*getFunction )( Argument1 , Argument2 , Argument3 ) const , void ( PL::AssetFactoryStore::*setFunction )( Argument1 , Argument2 , Argument3 , shared_ptr<ReturnType> ) , Argument1 arg1 , Argument2 arg2 , Argument3 arg3 , DateFunctionFactory *forwards ) const;

    Comme vous pouvez voir, il y a beaucoup de repetitions venant de différents cas. Je souhaiterais remplacer cela par des templates variadic mais je n'arrive pas à specialiser correctement pour tenir compte des cas où (notamment)
    class T, class ... arg
    Class T, class ... arg, class T2


    Une idée ?

    Merci d'avance.

    Matthieu

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 767
    Par défaut
    Si tu laisse la fonction déduire les types pour f(Args..., T), alors Args contiendra tous les types et T n'aura jamais de correspondance. Il faut mettre Args dans un contexte différent pour ensuite obtenir T.

    Je te propose un code simplifié que tu pourras adapter à ton cas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #include <iostream>
     
    struct A {
      void foo(int,int){}
      void bar(int){}
    };
     
    #define UNPACK(...) std::initializer_list<int>{(void(__VA_ARGS__),1)...}
     
    template<class... Args>
    struct caller
    {
      template<class... ExtraArgs>
      static void impl(Args & ... args, ExtraArgs & ... extra_args) {
        std::cout << "args:"; UNPACK(std::cout << ' ' << args); std::cout << '\n';
        std::cout << "extra:"; UNPACK(std::cout << ' ' << extra_args); std::cout << '\n';
      }
    };
     
    template<class... Args1, class... Args2>
    void f(void (A::*)(Args1...), void (A::*)(Args2...), Args1 && ... args) {
      caller<Args2...>::impl(args...);
    }
     
    int main() {
      f(&A::foo, &A::foo, 1, 2);
      f(&A::foo, &A::bar, 1, 2);
    }
    args: 1 2
    extra:
    args: 1
    extra: 2

  3. #3
    Membre habitué
    Inscrit en
    Février 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 11
    Par défaut
    Salut,

    Tout d'abord merci pour ta réponse.
    Ensuite, j'ai tourné le code mais en pratique, je ne comprends pas comment il fait vraiment le lien entre les composants. As-tu une doc lié à cet exemple ou plus de details ?

    Merci d'avance.
    Matthieu


    Citation Envoyé par jo_link_noir Voir le message
    Si tu laisse la fonction déduire les types pour f(Args..., T), alors Args contiendra tous les types et T n'aura jamais de correspondance. Il faut mettre Args dans un contexte différent pour ensuite obtenir T.

    Je te propose un code simplifié que tu pourras adapter à ton cas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #include <iostream>
     
    struct A {
      void foo(int,int){}
      void bar(int){}
    };
     
    #define UNPACK(...) std::initializer_list<int>{(void(__VA_ARGS__),1)...}
     
    template<class... Args>
    struct caller
    {
      template<class... ExtraArgs>
      static void impl(Args & ... args, ExtraArgs & ... extra_args) {
        std::cout << "args:"; UNPACK(std::cout << ' ' << args); std::cout << '\n';
        std::cout << "extra:"; UNPACK(std::cout << ' ' << extra_args); std::cout << '\n';
      }
    };
     
    template<class... Args1, class... Args2>
    void f(void (A::*)(Args1...), void (A::*)(Args2...), Args1 && ... args) {
      caller<Args2...>::impl(args...);
    }
     
    int main() {
      f(&A::foo, &A::foo, 1, 2);
      f(&A::foo, &A::bar, 1, 2);
    }

  4. #4
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    Ce que dit jo_link_noir, c'est que tu ne peux pas avoir une fonction template de type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template <typename A, typename... B, typename C>
    void foo(A, B..., C);
    Hélas, même le site de la référence (http://en.cppreference.com/w/cpp/lan...parameter_pack) n'est pas complet sur le sujet: "This section is incomplete. Reason: mention that it must be last in class template, but not function" (ce qui n'est que partiellement vrai.
    J'ai testé cette définition:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template <typename A, typename... B, typename C>
    void foo(A, B..., C);
    avec le dernier gcc, il accepte bizarrement une instantiation avec deux arguments, mais pas trois ou quatre.

    Donc l'idée de jo_link_noir est de capturer les paramètres template à deux endroits différents: dans une struct et dans une fonction membre de la struct.

    Une autre piste sinon, avec using:

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <typename ReturnType, typename... Args>
    using ptrCAFfn = ReturnType* ( PL::ConcreteAssetFactory::*)(Args...) const;
    template <typename ReturnType, typename... Args>
    using sptrCAFfn = shared_ptr<ReturnType>( PL::AssetFactoryStore::*)( Args... ) const;
    template <typename ReturnType, typename... Args>
    using vAFSfn = void ( PL::AssetFactoryStore::*)( Args... , shared_ptr<ReturnType> ) const;

    D'où:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template< class ReturnType, typename... Args >
    shared_ptr< ReturnType > Get(ptrCAFfn<ReturnType, Args...>,  sptrCAFfn<ReturnType, Args...>, vAFSfbFfn<ReturnType, Args...>,  Args...) const;

    J'ai testé la partie directive using qui est acceptée par le compilateur. Après je ne sais pas ce que donnerait la déduction de type pour get.

  5. #5
    Membre habitué
    Inscrit en
    Février 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 11
    Par défaut
    Bonjour,

    Merci pour ce retour. J'ai réussi à mieux apprehender la syntaxe mais j'ai encore un soucis de fusion d'arguments variadic.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
     
    virtual ScenarioDateFunction * GetOldOldTodayFunction() const { return new SmartScenarioDateFunction( Get( &PL::ConcreteAssetFactory::CreateOldOldTodayFunction , &PL::AssetFactoryStore::GetOldOldTodayFunction , &PL::AssetFactoryStore::SetOldOldTodayFunction ) ); }
     
     
     
    template< class ReturnType, typename... ArgumentsCreateFunctionComplementary, typename... ArgumentsStoreValues>
    		shared_ptr< ReturnType > Get(ReturnType * (PL::ConcreteAssetFactory::*createFunction)(ArgumentsStoreValues... ,ArgumentsCreateFunctionComplementary...) const, shared_ptr<ReturnType>(PL::AssetFactoryStore::*getFunction)(ArgumentsStoreValues...) const, void (PL::AssetFactoryStore::*setFunction)(ArgumentsStoreValues..., shared_ptr<ReturnType>), ArgumentsStoreValues... arg1, ArgumentsCreateFunctionComplementary...  arg2) const;
    J'obtiens l'erreur suivante qui indique la mauvaise fusion. J'ai trouvé sur internet des méthodes plus complexes mais je ne peux pas les appliquer pour permettre d'utiliser l'interface actuelle et de déduire automatiquement la function template. Une idée ?

    Error 1 error C2780: 'std::shared_ptr<_Ty> PL::ConcreteAssetFactory::Get(ReturnType *(__thiscall PL::ConcreteAssetFactory::* )(ArgumentsStoreValues...,ArgumentsCreateFunctionComplementary...) const,std::shared_ptr<_Ty> (__thiscall PL::AssetFactoryStore::* )(ArgumentsStoreValues...) const,void (__thiscall PL::AssetFactoryStore::* )(ArgumentsStoreValues...,std::shared_ptr<_Ty>),ArgumentsStoreValues...,ArgumentsCreateFunctionComplementary...) const' : expects 5 arguments - 3 provided (ConcreteUnderlyingGridCalculator.cpp) D:\test\Ing Model Library.V3\Inc\PricerLibrary\ConcreteAssetFactory.h 57



    Bien à vous,

    Matthieu


    Citation Envoyé par stendhal666 Voir le message
    Ce que dit jo_link_noir, c'est que tu ne peux pas avoir une fonction template de type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template <typename A, typename... B, typename C>
    void foo(A, B..., C);
    Hélas, même le site de la référence (http://en.cppreference.com/w/cpp/lan...parameter_pack) n'est pas complet sur le sujet: "This section is incomplete. Reason: mention that it must be last in class template, but not function" (ce qui n'est que partiellement vrai.
    J'ai testé cette définition:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template <typename A, typename... B, typename C>
    void foo(A, B..., C);
    avec le dernier gcc, il accepte bizarrement une instantiation avec deux arguments, mais pas trois ou quatre.

    Donc l'idée de jo_link_noir est de capturer les paramètres template à deux endroits différents: dans une struct et dans une fonction membre de la struct.

    Une autre piste sinon, avec using:

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <typename ReturnType, typename... Args>
    using ptrCAFfn = ReturnType* ( PL::ConcreteAssetFactory::*)(Args...) const;
    template <typename ReturnType, typename... Args>
    using sptrCAFfn = shared_ptr<ReturnType>( PL::AssetFactoryStore::*)( Args... ) const;
    template <typename ReturnType, typename... Args>
    using vAFSfn = void ( PL::AssetFactoryStore::*)( Args... , shared_ptr<ReturnType> ) const;

    D'où:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template< class ReturnType, typename... Args >
    shared_ptr< ReturnType > Get(ptrCAFfn<ReturnType, Args...>,  sptrCAFfn<ReturnType, Args...>, vAFSfbFfn<ReturnType, Args...>,  Args...) const;

    J'ai testé la partie directive using qui est acceptée par le compilateur. Après je ne sais pas ce que donnerait la déduction de type pour get.

  6. #6
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PL::ConcreteAssetFactory::*createFunction)(ArgumentsStoreValues... ,ArgumentsCreateFunctionComplementary...)
    Ok mets-toi un instant à la place du compilateur: comment peut-il savoir quels arguments il va nommer ArgumentsStoreValues et quels arguments il va nommer ArgumentsCreateFunctionComplementary? Il ne peut pas: par définition, le nombre d'arguments qu'un template variadique recouvre est indéterminé!
    Donc que faire?
    Il faut donner une façon au compilateur de départager. Tu peux suivre la voie de joe_link_noir, celle des using, ou encore d'autres, par exemple en utilisant des tuples qui regrouperont le type des arguments.

  7. #7
    Membre habitué
    Inscrit en
    Février 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 11
    Par défaut
    En fait, il sait qu'il y a 2 series d'arguments. Ct peut etre un mauvais exemple mais les fonctions qui sont passés en arguments permettent de définir l'appel de fonction sans équivoque en fait. En effet, les arguments store ou les complementarys sont passés à des endroits clairement differents. Donc, normalement, il peut déduire ce qu'il doit déduire. Je donnerais demain un bon exemple.
    Je pense donc que cela vient juste de la fusion entre les 2 arguments variadic.
    Merci.

    Matthieu

    Citation Envoyé par stendhal666 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PL::ConcreteAssetFactory::*createFunction)(ArgumentsStoreValues... ,ArgumentsCreateFunctionComplementary...)
    Ok mets-toi un instant à la place du compilateur: comment peut-il savoir quels arguments il va nommer ArgumentsStoreValues et quels arguments il va nommer ArgumentsCreateFunctionComplementary? Il ne peut pas: par définition, le nombre d'arguments qu'un template variadique recouvre est indéterminé!
    Donc que faire?
    Il faut donner une façon au compilateur de départager. Tu peux suivre la voie de joe_link_noir, celle des using, ou encore d'autres, par exemple en utilisant des tuples qui regrouperont le type des arguments.

  8. #8
    Membre habitué
    Inscrit en
    Février 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 11
    Par défaut
    Voilà.

    En fait les fonctions sont toutes du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    virtual JumpDateFunctionFactory * GetStockDividendJumps( const Stock *stock , long baseCurrency , DateFunctionFactory *forwards , DateFunctionFactory *forwardsWithoutDD ) const { return new JumpDateFunctionSmartFactory( Get2< JumpDateFunctionFactory , const Stock * , long >( &PL::ConcreteAssetFactory::CreateStockDividendJumps , &PL::AssetFactoryStore::GetStockDividendJumps , &PL::AssetFactoryStore::SetStockDividendJumps , stock , baseCurrency , forwards , forwardsWithoutDD ) ); }
    Dans la function Get tous les paramètres sont a priori definis univoquement. En effet, dans la function suivante, les paramètres variadic (PL::AssetFactoryStore::*getFunction)(ArgumentsStoreValues...) n'ont qu'une possibilité qui match. Le reste des arguments non repris dedans sont donc repris par arguments complémentaires. Es-tu d'accord ?

    Bien à toi,

    Matthieu

  9. #9
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    Dans la function Get tous les paramètres sont a priori definis univoquement
    Le compilateur est d'un autre avis: s'il attend 5 arguments c'est qu'il a "assigné" un argument concret à chaque template variadique "complémentaire" (ou deux à l'un et zéro à l'autre).

  10. #10
    Membre habitué
    Inscrit en
    Février 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 11
    Par défaut
    Oui, mais ce n'est pas plutôt un problème de merging des arguments ?
    En parcourant certains posts, j'ai lu que ça pouvait arriver si la fusion n'était pas explicitement faite.
    Comment tu le coderais sur ces fonctions là en fait ?

    Citation Envoyé par stendhal666 Voir le message
    Le compilateur est d'un autre avis: s'il attend 5 arguments c'est qu'il a "assigné" un argument concret à chaque template variadique "complémentaire" (ou deux à l'un et zéro à l'autre).

  11. #11
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    Je n'arrive pas bien à comprendre les données de ton problème.

    D'après ce que j'avais compris de ton premier post, tu avais différentes signatures pour la même fonction avec un nombre croissant d'arguments, mais toujours dans le même ordre et selon la même structure; pour simplifier un peu:

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <typename Ret, typename... Args> // le wrapper template
        int func( Ret(*)(Args...), Ret(*)(Args...), Args...) {
        return 1;
    }
     
    int foo(int a, int b) { return a+b; } // les fonctions concrètes
    int bar(int a) { return --a; }
     
    int main() {
        int i = func(&foo, &foo, 1, 2);
        int j = func(&bar, &bar, 2); // tout cela compile sans difficulté
    }

    Mais maintenant il semble que cela diffère un peu, puisque tu fais varier les arguments des différentes fonctions. Dans ce cas, je ferais un paramètre variadique par type de fonction + 1 dernier pour les arguments hors signature de fonction, et je ne tenterais pas de les fusionner:

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <typename Ret, typename... Args1, typename... Args2, typename... Args3>
        int func( Ret(*)(Args1...), Ret(*)(Args2...), Args3...) {
        return 1;
    }
     
    int foo(int a, int b) { return a+b; }
    int bar(int a) { return --a; }
     
    int main() {
        int i = func(&foo, &bar, 1, 2, 3);
    }

    Quitte à vérifier si les arguments correspondent avec des static_assert.

    Cependant, comme je te le disais, j'ai un peu de mal à comprendre les données de ton problème, donc je tombe peut-être à côté.

  12. #12
    Membre habitué
    Inscrit en
    Février 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 11
    Par défaut
    Ok, merci pour les détails et l'exemple.

    Effectivement, c'est plus compliqué que je ne le pensais au début.
    En fait, la function GET est tjrs du style
    Get(CreateFunc (Arguments1, Arguments2), Get (Arguments 2, Returntype), Set(Arguments1,Arguments2) ).
    L'appel à la function est tjrs du style
    Get<return type>(Createfunc,GetFunc,SetFunc, list of arguments)
    Le return type n'est pas déduit en C++ 11 si j'ai bien compris.
    Donc, je suis un peu obligé de fusionner sauf si je réécris toutes les fonctions (on parle de 200 fonctions).
    ?

  13. #13
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    Le return type n'est pas déduit en C++ 11 si j'ai bien compris.
    De quel type de retour parles-tu? Si c'est celui des fonctions en argument, il peut être déduit, comme dans mon exemple; si c'est celui de la fonction get appelée, il peut être déduit par le mot clé auto à partir du type suivant la directive return dans la fonction;

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template </* ... */>
    auto Get(CreateFunc (Arguments1, Arguments2), Get (Arguments 2, Returntype), Set(Arguments1,Arguments2) ) {
       // ...
       return shared_ptr<Return_type_of_get_function>( /* ... */ );
    }

    En fait, la function GET est tjrs du style
    Get(CreateFunc (Arguments1, Arguments2), Get (Arguments 2, Returntype), Set(Arguments1,Arguments2) ).
    L'appel à la function est tjrs du style
    Get<return type>(Createfunc,GetFunc,SetFunc, list_of_arguments)
    Alors tout dépend de list_of_arguments: s'il est possible de déduire ce qui dedans correspond à Arguments1 et à Arguments2 (par exemple les n premiers sont arguments1), c'est faisable au prix d'une complexité supplémentaire mais qui vaudrait le coup si tu peux simplifier de 200 fonctions à une fonction template. Je pourrais te donner des pistes si c'est bien cela.

  14. #14
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    C'est vrai en C++14 mais pas en C++11 où il faudra utiliser auto et decltype.
    Exemple C++11 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <class T0, class T1>
    auto fct(T0 const & t0, T1 const & t1) -> decltype(t0 + t1)
    {
        return t0 + t1;
    }
    En C++14, plus besoin du -> decltype(t0 + t1)

  15. #15
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,
    Mon dieu!!!

    Vouloir créer une copie non pas de un mais d'un ensemble d'éléments ayant typiquement sémantique d'entité sans même penser à utiliser les pointeurs intelligents!!! Y en a vraiment qui veulent se faire du mal pour rien... Rassures moi, ca fait au moins beaucoup de bien quand ca s'arrête

    Bon, , mais si mon intervention éveille en toi le moindre intérêt, je viendrai volontiers expliquer cela plus longuement
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Utilisation des templates
    Par vanitom dans le forum MFC
    Réponses: 21
    Dernier message: 01/08/2007, 12h07
  2. Réponses: 1
    Dernier message: 18/04/2006, 13h24
  3. [XSL]portée des templates??
    Par luta dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 23/02/2006, 11h53
  4. [XSL] utilisation des templates
    Par KibitO dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 16/12/2005, 16h54
  5. Utilisation des templates
    Par mikky dans le forum C++
    Réponses: 1
    Dernier message: 14/09/2005, 13h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo