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

C++ Discussion :

std::list ou std::vector comme argument de template


Sujet :

C++

  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 354
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 354
    Points : 1 419
    Points
    1 419
    Par défaut std::list ou std::vector comme argument de template
    bonjour,

    je dois creer une fonction du genre: create_set_from_list
    mais j'aimerais que list soit un vector ou une list

    pour l'instant j'ai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    template<class T>
    std::set<T> create_set_from_list(const std::vector<T> &list)
    {
        std::set<T> myset;
        typename std::vector<T>::const_iterator it;
     
        for( it=list.begin(); it!=list.end(); ++it) {
            myset.insert(*it);
        }
     
        return myset;
    }
    comment rendre std::vector un argument du template?

    (je n'obtiens que des erreurs de compilation :-/)

  2. #2
    Invité
    Invité(e)
    Par défaut
    A priori c'est impossible d'utiliser std::vector comme un paramètre template template : la norme ne précise pas le nombre d'argument des class standards. Par contre tu peux faire quelquechose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template<class T, class Cont = std::vector<T> >
    std::set<T> create_set_from_list(const std::vector<T> &list)
    {
    //....
    }
    Peut-être sera-t-il possible de définir la signature d'une class template standard en C++11, avec les template aliases, à voir quand ce sera implémenté

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 354
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 354
    Points : 1 419
    Points
    1 419
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template<class T, template<typename,typename> class L, class Alloc>
    std::set<T> create_set_from_list(const L<T,Alloc> &list)
    {
        std::set<T> myset;
        typename L<T,Alloc>::const_iterator it;
     
        for( it=list.begin(); it!=list.end(); ++it) {
            myset.insert(*it);
        }
     
        return myset;
    }
    marche sur macosx gcc 4.2.1

    mais ce n'est pas portable alors?

  4. #4
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Tu veux de la généricité? Alors demande un range. (une pair d'itérateur).

  5. #5
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 617
    Points
    15 617
    Par défaut
    Bonjour

    Plein de solution pour ce que tu veux faire :
    - ne pas créer de fonction
    Tu peux créer un set à partir d'un vector ou list directement, à l'initialisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::set<int> s (v.begin(), v.end());
    ou avec insert() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::set<int> s;
    s.insert(v.begin(), v.end());
    ou avec std::copy() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::set<int> s;
    std::copy(v.begin(), v.end(), std::inserter(s, s.begin()));
    - habituellement, pour les algorithmes de la stl, on passe un paire d'iterator (ou un range, comme dit Goten) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    template<class ITERATOR>
    std::set<typename ITERATOR::value_type> create_set_from_list2(ITERATOR first, ITERATOR last)
    {
        std::set<typename ITERATOR::value_type> myset;
        typename ITERATOR::const_iterator it;
     
        for( it=first; it!=last; ++it)
        {
            myset.insert(*it);
        }
     
        return myset;
    }
    - Sinon, tu peux considérer le conteneur comme étant lui même le paramètre template :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    template<class CONT>
    std::set<typename CONT::value_type> create_set_from_list2(const CONT& list)
    {
        std::set<typename CONT::value_type> myset;
        typename CONT::const_iterator it;
     
        for( it=list.begin(); it!=list.end(); ++it)
        {
            myset.insert(*it);
        }
     
        return myset;
    }
    Voilà, je crois avoir fait le tour
    Bonne continuation

  6. #6
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 354
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 354
    Points : 1 419
    Points
    1 419
    Par défaut
    génial!

    j'ai utilisé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::set<int> s;
    s.insert(v.begin(), v.end());
    cela m'évitait de faire une copie :-)

    merci beaucoup pour vos réponses

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut
    Citation Envoyé par epsilon68 Voir le message
    génial!

    j'ai utilisé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::set<int> s;
    s.insert(v.begin(), v.end());
    C'est, en tout cas, le code le plus simple ...

    Tu aurais, d'ailleurs, pu utiliser directement le constructeur de set, qui fonctionne avec les itérateurs compatibles:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::set<int> s(v.begin(), v.end());
    Mais...
    cela m'évitait de faire une copie :-)
    BEEEEEPPP... hé non, merci d'avoir essayé ...

    Insert fait, d'office, une copie de l'objet, quel que soit l'objet, quel que soit le conteneur au départ duquel on appelle cette fonction (tout comme push_bak/push_front pour les conteneurs qui les ont)...

    Au mieux, on peut dire que ce qui est pointé par un pointeur n'est pas copié (mais le pointeur l'est, quant à lui bel et bien )

  8. #8
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 354
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 354
    Points : 1 419
    Points
    1 419
    Par défaut
    le set<std::string> etait un membre d'une classe

    donc je ne peux pas utiliser le constructeur car je dois l'initialiser dans une autre fonction, du style "create".

    eviter la copie signifiait la copie du set si je faisais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_set = create_from_list(myvalues);
    la il y a une copie.

  9. #9
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 617
    Points
    15 617
    Par défaut
    @koala01 et epsilon68
    Vous ne parlez pas de la même copie. koala01 parle de la copie de vector -> set et epsilon68 parle de la copie de set (interne à la fonction) -> set (externe)

    J'ai un doute... il y a bien copie du set vers le set lors du retour de le fonction (pas de swap ou move qui copierait que le pointeur interne de set et non l'ensemble des données) ?

    (à mon avis, il y a copie, mais on sait jamais avec les optimisations des compilateurs et avec c++0x)

  10. #10
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    nrvo. (y'a pas de copie)

  11. #11
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 354
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 354
    Points : 1 419
    Points
    1 419
    Par défaut
    certains compilateurs peuvent ne pas faire de nrvo (surement mineur)
    en tous les cas, si on peut éviter le doute....

  12. #12
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 617
    Points
    15 617
    Par défaut
    Merci Goten, je me doutais qu'il devait y avoir une optimisation quelque part

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. std::stable_sort et std::list
    Par darkman19320 dans le forum C++
    Réponses: 3
    Dernier message: 02/10/2012, 11h40
  2. Convertir un Generic::List en std::list
    Par Clemsgc dans le forum SL & STL
    Réponses: 7
    Dernier message: 19/06/2009, 00h22
  3. [Tuto] Recherche de tutoriel sur std::list et std::vector
    Par pegase06 dans le forum SL & STL
    Réponses: 27
    Dernier message: 24/07/2007, 16h23
  4. Réponses: 18
    Dernier message: 03/07/2006, 15h53
  5. Réponses: 14
    Dernier message: 16/05/2006, 11h26

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