215 votes

Comment initialiser std::vector en C-gamme de style?

Quel est le moyen le moins cher pour initialiser un std::vector à partir d'un C-gamme de style?

Exemple: Dans la classe suivante, j'ai un vector, mais en raison de restrictions extérieures, les données seront transmises en tant que C-gamme de style:

class Foo {
  std::vector<double> w_;
public:
  void set_data(double* w, int len){
   // how to cheaply initialize the std::vector?
}

Évidemment, je peux appeler w_.resize() , puis une boucle sur les éléments, ou appelez - std::copy(). Existe-il des meilleures méthodes?

287voto

Pavel Minaev Points 60647

N'oubliez pas que vous pouvez traiter des pointeurs comme des itérateurs:

w_.assign(w, w + len);

47voto

Mark B Points 60200

Vous utilisez le mot initialiser il est donc difficile de savoir si c'est une fois l'affectation ou peut se produire plusieurs fois.

Si vous avez juste besoin d'un temps d'initialisation, vous pouvez le mettre dans le constructeur et utiliser les deux itérateur vecteur constructeur:

Foo::Foo(double* w, int len) : w_(w, w + len) { }

Utiliser autrement affecter comme suggéré précédemment:

void set_data(double* w, int len)
{
    w_.assign(w, w + len);
}

12voto

Aaron McDaid Points 7761

Vous pouvez "apprendre" la taille du tableau automatiquement:

template<typename T, size_t N>
void set_data(const T (&w)[N]){
    w_.assign(w, w+N);
}

Heureusement, vous pouvez changer l'interface de set_data comme ci-dessus. Il accepte toujours d'un C-gamme de style en tant que premier argument. Il arrive juste à le prendre en référence.


Comment ça marche

[ Mise à jour: Voir ici pour une discussion plus complète sur l'apprentissage de la taille ]

Ici, c'est un plus de solution générale:

template<typename T, size_t N>
void copy_from_array(vector<T> &target_vector, const T (&source_array)[N]) {
    target_vector.assign(source_array, source_array+N);
}

Cela fonctionne parce que le tableau est passé comme une référence à un tableau. En C/C++, vous ne pouvez pas passer un tableau à une fonction, au lieu de cela, il se désintègre à un pointeur, et vous perdez la taille. Mais en C++, vous pouvez passer une référence à la matrice.

Passage d'un tableau par référence nécessite les types de correspondre exactement. La taille d'un tableau est une partie de son type. Cela signifie que nous pouvons utiliser le paramètre de modèle N pour apprendre la taille pour nous.

Il pourrait être encore plus simple d'avoir cette fonction qui retourne un vecteur. Avec appropriée les optimisations du compilateur en effet, ce devrait être plus rapide qu'il n'y paraît.

template<typename T, size_t N>
vector<T> convert_array_to_vector(const T (&source_array)[N]) {
    return vector<T>(source_array, source_array+N);
}

0voto

Janusz Lenar Points 487

std::vector<double>::assign est le chemin à parcourir, car il est peu de code. Mais comment ça fonctionne, en fait? Ne pas redimensionner, puis copier? En MS de la mise en œuvre de la STL, je suis en utilisant il fait exactement.

J'ai peur, il n'y a pas de moyen plus rapide à mettre en œuvre (ré)initialisation de votre std::vector.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X