Quelle est la façon la plus simple d'initialiser un vecteur std :: avec des éléments codés en dur?

612

Je peux créer un tableau et l'initialiser comme ceci:

int a[] = {10, 20, 30};

Comment puis-je créer un std::vectoret l'initialiser de la même manière élégante?

La meilleure façon que je connaisse est:

std::vector<int> ints;

ints.push_back(10);
ints.push_back(20);
ints.push_back(30);

Y a-t-il une meilleure façon?

Agnel Kurian
la source
1
si vous n'allez pas changer la taille des entiers après l'initialisation, pensez à utiliser le tableau tr1.
zr.
@zr, vous m'avez curieux ... si j'avais besoin d'une taille fixe, ne pourrais-je pas utiliser eux-mêmes de vieux tableaux simples? En regardant le tableau tr1 en ce moment ...
Agnel Kurian
2
tr1::arrayest utile car les tableaux ordinaires ne fournissent pas l'interface des conteneurs STL
Manuel
Changement du titre pour en faire explicitement une question C ++ 03. Cela semblait plus facile que de passer au travers et de corriger toutes les réponses pour donner un sens au nouveau standard C ++.
TED le
C'est ce qu'on appelle l' initialisation de la liste .
Alan Dawkins

Réponses:

548

Une méthode consisterait à utiliser le tableau pour initialiser le vecteur

static const int arr[] = {16,2,77,29};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
Yacoby
la source
7
@Agnel Cela fonctionnera bien sans staticou const, mais ils expliquent tous les deux comment il doit être utilisé et permettent au compilateur d'effectuer des optimisations supplémentaires.
Yacoby
68
Je n'ai pas facturé cela, mais j'ai été tenté. Principalement parce que cela ne vous évite presque rien en utilisant simplement le tableau initialisé en premier lieu. Cependant, c'est vraiment la faute de C ++, pas la vôtre.
TED
2
Pouvez-vous expliquer pourquoi vous utilisez ces paramètres lors de la définition du vecteur vec.
DomX23
13
sizeof (array) est l'une des rares exceptions qui permet d'obtenir la taille totale des éléments du tableau et NON la dimension du pointeur arr. Donc, fondamentalement, il utilise vector (pointer_to_first_element, pointer_to_first_element + size_in_bytes_of_the_whole_array / size_of_one_element) qui est: vector (pointer_to_first_element, pointer_after_final_element). Le type est déjà donné avec le <int>, donc le vecteur sait combien est un élément. N'oubliez pas que les itérateurs peuvent être traités comme des pointeurs, vous utilisez donc essentiellement le constructeur vectoriel (début de l'itérateur, fin de l'itérateur)
Johnny Pauling
11
@TED: Parfois, vous devez modifier le vecteur résultant. Par exemple, vous devrez peut-être toujours avoir certains paramètres par défaut et parfois en ajouter quelques-uns personnalisés.
DarkWanderer
642

Si votre compilateur prend en charge C ++ 11, vous pouvez simplement faire:

std::vector<int> v = {1, 2, 3, 4};

Ceci est disponible dans GCC à partir de la version 4.4 . Malheureusement, VC ++ 2010 semble être à la traîne à cet égard.

Alternativement, la bibliothèque Boost.Assign utilise la magie non macro pour permettre ce qui suit:

#include <boost/assign/list_of.hpp>
...
std::vector<int> v = boost::assign::list_of(1)(2)(3)(4);

Ou:

#include <boost/assign/std/vector.hpp>
using namespace boost::assign;
...
std::vector<int> v;
v += 1, 2, 3, 4;

Mais gardez à l'esprit que cela a des frais généraux (en gros, list_ofconstruit un std::dequesous le capot), donc pour un code critique pour les performances, vous feriez mieux de faire comme Yacoby le dit.

Manuel
la source
Étant donné que les vecteurs sont auto-dimensionnés, serait-il correct de l'initialiser comme vide aussi? Comme chez le constructeur this->vect = {};:?
Azurespot
3
@Azurespot Vous pouvez simplement l'initialiser, et il sera vide:std::vector<T> vector;
Luke
2
Juste au cas où quelqu'un pourrait être curieux std::vector<int> v = {1, 2, 3, 4};, des vecteurs initializer list constructorseront appelés pour ce type d'initialisation, son doc peut être trouvé dans la C++ 11section .
simomo
103

Si vous le pouvez, utilisez la méthode moderne C ++ [11,14,17, ...]:

std::vector<int> vec = {10,20,30};

L'ancienne façon de boucler sur un tableau de longueur variable ou d'utiliser sizeof()est vraiment terrible pour les yeux et complètement inutile en termes de surcharge mentale. Beurk.

Adam Erickson
la source
2
En toute honnêteté, c'était à l'origine une question C ++ 03, mais j'espère que les personnes / entreprises adopteront les nouvelles normes. C ++ a toujours besoin d'une implémentation de tableau de longueur variable (VLA) dans la bibliothèque standard similaire à ce qui est disponible dans Eigen et Boost.
Adam Erickson
Malheureusement, cette approche est problématique dans certains cas, par exemple open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467 . Beurk.
Courses de légèreté en orbite le
Si "l'initialisation de la liste d'un agrégat à partir d'un objet du même type" est votre truc, il y a probablement de plus gros problèmes dans votre base de code ... Je ne peux penser à aucune application où cela justifierait les problèmes de débogage.
Adam Erickson
77

En C ++ 0x, vous pourrez le faire de la même manière que vous l'avez fait avec un tableau, mais pas dans la norme actuelle.

Avec uniquement la prise en charge des langues, vous pouvez utiliser:

int tmp[] = { 10, 20, 30 };
std::vector<int> v( tmp, tmp+3 ); // use some utility to avoid hardcoding the size here

Si vous pouvez ajouter d'autres bibliothèques, vous pouvez essayer boost :: assignation:

vector<int> v = list_of(10)(20)(30);

Pour éviter de coder en dur la taille d'un tableau:

// option 1, typesafe, not a compile time constant
template <typename T, std::size_t N>
inline std::size_t size_of_array( T (&)[N] ) {
   return N;
}
// option 2, not typesafe, compile time constant
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))

// option 3, typesafe, compile time constant
template <typename T, std::size_t N>
char (&sizeof_array( T(&)[N] ))[N];    // declared, undefined
#define ARRAY_SIZE(x) sizeof(sizeof_array(x))
David Rodríguez - dribeas
la source
Bien sûr, je n'ai pas déprécié mais j'ai quand même une question: quand la taille d'un tableau n'est-elle pas une constante de temps de compilation? C'est-à-dire, dans quels cas utiliseriez-vous la première solution dans votre deuxième extrait plutôt que la troisième?
Manuel
4
@Manuel, la taille du tableau fait partie du type, et en tant que telle, c'est une constante de temps de compilation. Maintenant, l'option 1 utilise cette constante de temps de compilation «N» comme valeur de retour pour une fonction. Le retour d'une fonction n'est pas une heure de compilation, mais une valeur d'exécution, même si elle sera probablement alignée comme valeur constante à l'endroit de l'appel. La différence est que vous ne pouvez pas faire:, int another[size_of_array(array)]alors que vous pouvez le faire int another[ARRAY_SIZE(array)].
David Rodríguez - dribeas
1
Dans l'option 3: je ne comprends pas vraiment ce que vous voulez dire par «déclaré, non défini»? La variable ne prendra donc pas de mémoire supplémentaire?
To1ne
1
@ To1ne qui est en fait une déclaration de fonction, pas une variable. La raison ou la définition est que nous ne voulons pas réellement la fonction pour autre chose que l' sizeofexpression qui n'a pas besoin d'une définition. Bien que vous puissiez réellement fournir une définition, le faire correctement nécessiterait l'allocation statique d'un tableau et le renvoi d'une référence à celui-ci, et la question suivante serait ce qui aurait du sens en tant que valeurs pour le tableau? (Notez également que cela signifie un tableau par combinaison type / taille des instanciations de la fonction!) Étant donné que ce n'est pas une utilisation sensée, je préfère l'éviter.
David Rodríguez - dribeas
1
@mhd: Vous ne pouvez pas construire un tableau vide dans la langue. 'int arr [0] = {};' n'est pas un code C ++ valide. Mais vous avez raison: si vous voulez initialiser un vecteur vide et un vecteur non vide, vous devrez utiliser des constructions différentes. Depuis C ++ 11, ce n'est pas un problème car vous pouvez utiliser le constructeur de liste d'initialisation
David Rodríguez - dribeas
61

En C ++ 11:

#include <vector>
using std::vector;
...
vector<int> vec1 { 10, 20, 30 };
// or
vector<int> vec2 = { 10, 20, 30 };

Utilisation de boost list_of:

#include <vector>
#include <boost/assign/list_of.hpp>
using std::vector;
...
vector<int> vec = boost::assign::list_of(10)(20)(30);

Utilisation de boost assign:

#include <vector>
#include <boost/assign/std/vector.hpp>
using std::vector;
...
vector<int> vec;
vec += 10, 20, 30;

STL conventionnel:

#include <vector>
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );

STL conventionnel avec macros génériques:

#include <vector>
#define ARRAY_SIZE(ar) (sizeof(ar) / sizeof(ar[0])
#define ARRAY_END(ar) (ar + ARRAY_SIZE(ar))
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec (arr, ARRAY_END(arr));

STL conventionnel avec une macro d'initialisation vectorielle:

#include <vector>
#define INIT_FROM_ARRAY(ar) (ar, ar + sizeof(ar) / sizeof(ar[0])
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec INIT_FROM_ARRAY(arr);
mbells
la source
2
C ++ 11 prend également en charge std::beginet std::endpour tableau, de sorte qu'un vecteur peut également être initialisé comme static const int arr[] = {10,20,30}; vector<int> vec(begin(arr), end(arr));.
Jaege
54

Je pensais juste jeter mes 0,02 $. J'ai tendance à déclarer ceci:

template< typename T, size_t N >
std::vector<T> makeVector( const T (&data)[N] )
{
    return std::vector<T>(data, data+N);
}

dans un en-tête d'utilitaire quelque part et tout ce qui est requis est:

const double values[] = { 2.0, 1.0, 42.0, -7 };
std::vector<double> array = makeVector(values);

Mais je ne peux pas attendre C ++ 0x. Je suis bloqué car mon code doit également être compilé dans Visual Studio. Huer.

M. Tibbits
la source
1
Cette technique peut également être utilisée pour surcharger une fonction pour accepter un tableau de taille typée.
Andres Riofrio
4
Pouvez-vous expliquer la const T (&data)[N]partie? Comment la taille du tableau est-elle déduite dans votre appel makeVector(values)?
Patryk
36

Avant C ++ 11:

Méthode 1 =>

vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));
vector<int>v;

Méthode 2 =>

 v.push_back(SomeValue);

C ++ 11 ci-dessous est également possible

vector<int>v = {1, 3, 5, 7};
UN J
la source
28

Commençant par:

int a[] = {10, 20, 30}; //i'm assuming a is just a placeholder

Si vous n'avez pas de compilateur C ++ 11 et que vous ne souhaitez pas utiliser boost:

const int a[] = {10, 20, 30};
const std::vector<int> ints(a,a+sizeof(a)/sizeof(int)); //make it const if you can

Si vous n'avez pas de compilateur C ++ 11 et pouvez utiliser boost:

#include <boost/assign.hpp>
const std::vector<int> ints = boost::assign::list_of(10)(20)(30);

Si vous avez un compilateur C ++ 11:

const std::vector<int> ints = {10,20,30};
Carl
la source
22

Pour l'initialisation vectorielle -

vector<int> v = {10,20,30}

peut être fait si vous avez un compilateur c ++ 11.

Sinon, vous pouvez avoir un tableau de données, puis utiliser une boucle for.

int array[] = {10,20,30}
for(unsigned int i=0; i<sizeof(array)/sizeof(array[0]); i++)
{
     v.push_back(array[i]);
}

En dehors de ceux-ci, il existe plusieurs autres façons décrites ci-dessus en utilisant du code. À mon avis, ces méthodes sont faciles à mémoriser et rapides à écrire.

Tush_08
la source
21

La façon la plus simple de le faire est:

vector<int> ints = {10, 20, 30};
Paul Baltescu
la source
4
Quel compilateur? Utilisez-vous C ++ 11 ici?
Agnel Kurian
g ++ 4.6.3 avec -std = c ++ 0x.
Paul Baltescu
16

Je construis ma propre solution en utilisant va_arg. Cette solution est compatible C ++ 98.

#include <cstdarg>
#include <iostream>
#include <vector>

template <typename T>
std::vector<T> initVector (int len, ...)
{
  std::vector<T> v;
  va_list vl;
  va_start(vl, len);
  for (int i = 0; i < len; ++i)
    v.push_back(va_arg(vl, T));
  va_end(vl);
  return v;
}

int main ()
{
  std::vector<int> v = initVector<int> (7,702,422,631,834,892,104,772);
  for (std::vector<int>::const_iterator it = v.begin() ; it != v.end(); ++it)
    std::cout << *it << std::endl;
  return 0;
}

Démo

aloisdg passe à codidact.com
la source
14

Si votre compilateur prend en charge les macros Variadic (ce qui est vrai pour la plupart des compilateurs modernes), vous pouvez utiliser la macro suivante pour transformer l'initialisation vectorielle en une ligne:

#define INIT_VECTOR(type, name, ...) \
static const type name##_a[] = __VA_ARGS__; \
vector<type> name(name##_a, name##_a + sizeof(name##_a) / sizeof(*name##_a))

Avec cette macro, vous pouvez définir un vecteur initialisé avec un code comme celui-ci:

INIT_VECTOR(int, my_vector, {1, 2, 3, 4});

Cela créerait un nouveau vecteur d'entiers nommé my_vector avec les éléments 1, 2, 3, 4.

Matt Ball
la source
13

Si vous ne souhaitez pas utiliser boost, mais souhaitez profiter de la syntaxe comme

std::vector<int> v;
v+=1,2,3,4,5;

il suffit d'inclure ce morceau de code

template <class T> class vector_inserter{
public:
    std::vector<T>& v;
    vector_inserter(std::vector<T>& v):v(v){}
    vector_inserter& operator,(const T& val){v.push_back(val);return *this;}
};
template <class T> vector_inserter<T> operator+=(std::vector<T>& v,const T& x){
    return vector_inserter<T>(v),x;
}
Piti Ongmongkolkul
la source
1
Je n'ai pas pu comprendre comment utiliser ce code, mais cela semble intéressant.
Daniel Buckmaster
C'est comme l'un des commentaires ci-dessus dit. Juste surcharger + = et opérateur virgule. Mettre des parenthèses pour plus de clarté: ((((v+=1),2),3),4),5) Voici comment cela fonctionne: tout d'abord, vector<T> += Trenvoie un vecteur_inserter permet de l'appeler viqui encapsule le vecteur d'origine, puis d' vi,Tajouter T au vecteur d'origine qui viencapsule et de le retourner lui-même afin que nous puissions vi,Trecommencer.
Piti Ongmongkolkul
ce code n'a pas fonctionné correctement sur gcc 4.2.1 je pense à cause du retour de référence à une variable locale à l'intérieur de l'opérateur + = mais l'idée est excellente. j'ai édité le code et il apparaît un autre constructeur de copie. le flux est maintenant -> + = -> ctor -> virgule -> copie -> dtor -> virgule ...... -> virgule -> dtor.
Yevhen
J'aurais probablement surchargé << au lieu de + =. Au moins << a déjà de vagues règles sur les effets secondaires en raison des décalages de bits et des
couts
11

En C ++ 11:

static const int a[] = {10, 20, 30};
vector<int> vec (begin(a), end(a));
BufBills
la source
21
Si vous utilisez déjà C ++ 11, vous pouvez tout aussi bien opter pour l'approche directe - vector<int> arr = {10, 20, 30};.
Bernhard Barker
En fait, j'avais un int [] (certains C lib) et je voulais pousser dans un vecteur (C ++ lib). Cette réponse a aidé, le reste n'a pas ;-)
Nébuleuse
10

vous pouvez le faire en utilisant boost :: assign.

vector<int> values;  
values += 1,2,3,4,5,6,7,8,9;

détail ici

f4.
la source
19
Je n'ai pas vu de pire cas de surcharge des opérateurs depuis longtemps. Est-ce +=qu'il y a 1,2,3,4 .. à la fin des valeurs, ou ajoute- t-il 1 au 1er élément, 2 au 2e élément, 3 au 3e élément (comme une syntaxe comme celle-ci devrait dans MATLAB- comme les langues)
bobobobo
10

Une question en double plus récente a cette réponse par Viktor Sehr . Pour moi, il est compact, visuellement attrayant (on dirait que vous `` enfoncez '' les valeurs dans), ne nécessite pas c ++ 11 ou un module tiers, et évite d'utiliser une variable supplémentaire (écrite). Voici comment je l'utilise avec quelques modifications. Je peux passer à l'extension de la fonction de vector et / ou va_arg dans le futur intead.


// Based on answer by "Viktor Sehr" on Stack Overflow
// https://stackoverflow.com/a/8907356
//
template <typename T>
class mkvec {
public:
    typedef mkvec<T> my_type;
    my_type& operator<< (const T& val) {
        data_.push_back(val);
        return *this;
    }
    my_type& operator<< (const std::vector<T>& inVector) {
        this->data_.reserve(this->data_.size() + inVector.size());
        this->data_.insert(this->data_.end(), inVector.begin(), inVector.end());
        return *this;
    }
    operator std::vector<T>() const {
        return data_;
    }
private:
    std::vector<T> data_;
};

std::vector<int32_t>    vec1;
std::vector<int32_t>    vec2;

vec1 = mkvec<int32_t>() << 5 << 8 << 19 << 79;  
// vec1 = (5,8,19,79)
vec2 = mkvec<int32_t>() << 1 << 2 << 3 << vec1 << 10 << 11 << 12;  
// vec2 = (1,2,3,5,8,19,79,10,11,12)
Autremusketeer
la source
7

Les méthodes ci-dessous peuvent être utilisées pour initialiser le vecteur en c ++.

  1. int arr[] = {1, 3, 5, 6}; vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));

  2. vector<int>v; v.push_back(1); v.push_back(2); v.push_back(3); etc

  3. vector<int>v = {1, 3, 5, 7};

Le troisième est autorisé uniquement en C ++ 11.

Geai
la source
5

Il y a beaucoup de bonnes réponses ici, mais comme je suis arrivé indépendamment avant de lire ceci, j'ai pensé que je jetterais le mien ici de toute façon ...

Voici une méthode que j'utilise pour cela qui fonctionnera universellement sur les compilateurs et les plates-formes:

Créez une structure ou une classe en tant que conteneur pour votre collection d'objets. Définissez une fonction de surcharge d'opérateur pour <<.

class MyObject;

struct MyObjectList
{
    std::list<MyObject> objects;
    MyObjectList& operator<<( const MyObject o )
    { 
        objects.push_back( o );
        return *this; 
    }
};

Vous pouvez créer des fonctions qui prennent votre structure en paramètre, par exemple:

someFunc( MyObjectList &objects );

Ensuite, vous pouvez appeler cette fonction, comme ceci:

someFunc( MyObjectList() << MyObject(1) <<  MyObject(2) <<  MyObject(3) );

De cette façon, vous pouvez créer et transmettre une collection d'objets de taille dynamique à une fonction en une seule ligne épurée!

BuvinJ
la source
4

Si vous voulez quelque chose sur le même ordre général que Boost :: assign sans créer de dépendance sur Boost, ce qui suit est au moins vaguement similaire:

template<class T>
class make_vector {
    std::vector<T> data;
public:
    make_vector(T const &val) { 
        data.push_back(val);
    }

    make_vector<T> &operator,(T const &t) {
        data.push_back(t);
        return *this;
    }

    operator std::vector<T>() { return data; }
};

template<class T> 
make_vector<T> makeVect(T const &t) { 
    return make_vector<T>(t);
}

Bien que je souhaite que la syntaxe pour l'utiliser soit plus propre, elle n'est toujours pas particulièrement horrible:

std::vector<int> x = (makeVect(1), 2, 3, 4);
Jerry Coffin
la source
4
typedef std::vector<int> arr;

arr a {10, 20, 30};       // This would be how you initialize while defining

Pour compiler l'utilisation:

clang++ -std=c++11 -stdlib=libc++  <filename.cpp>
shaveenk
la source
La question indique C ++ 03 (pas 11)
Mike P
1
Je pense qu'il n'a pas précisé 03 quand j'ai répondu à cela. Mais je ne m'en souviens pas parfaitement. Cependant, c'est toujours une réponse utile pour quelqu'un qui cherche une solution rapide.
shaveenk
4
// Before C++11
// I used following methods:

// 1.
int A[] = {10, 20, 30};                              // original array A

unsigned sizeOfA = sizeof(A)/sizeof(A[0]);           // calculate the number of elements

                                                     // declare vector vArrayA,
std::vector<int> vArrayA(sizeOfA);                   // make room for all
                                                     // array A integers
                                                     // and initialize them to 0 

for(unsigned i=0; i<sizeOfA; i++)
    vArrayA[i] = A[i];                               // initialize vector vArrayA


//2.
int B[] = {40, 50, 60, 70};                          // original array B

std::vector<int> vArrayB;                            // declare vector vArrayB
for (unsigned i=0; i<sizeof(B)/sizeof(B[0]); i++)
    vArrayB.push_back(B[i]);                         // initialize vArrayB

//3.
int C[] = {1, 2, 3, 4};                              // original array C

std::vector<int> vArrayC;                            // create an empty vector vArrayC
vArrayC.resize(sizeof(C)/sizeof(C[0]));              // enlarging the number of 
                                                     // contained elements
for (unsigned i=0; i<sizeof(C)/sizeof(C[0]); i++)
     vArrayC.at(i) = C[i];                           // initialize vArrayC


// A Note:
// Above methods will work well for complex arrays
// with structures as its elements.
sg7
la source
4

Si le tableau est:

int arr[] = {1, 2, 3};
int len = (sizeof(arr)/sizeof(arr[0])); // finding length of array
vector < int > v;
std:: v.assign(arr, arr+len); // assigning elements from array to vector 
FaridLU
la source
4

Il est assez pratique de créer un vecteur en ligne sans définir de variable lors de l'écriture du test, par exemple:

assert(MyFunction() == std::vector<int>{1, 3, 4}); // <- this.
Daniel Stracaboško
la source
3

En relation, vous pouvez utiliser ce qui suit si vous voulez avoir un vecteur complètement prêt à aller dans une déclaration rapide (par exemple, passer immédiatement à une autre fonction):

#define VECTOR(first,...) \
   ([](){ \
   static const decltype(first) arr[] = { first,__VA_ARGS__ }; \
   std::vector<decltype(first)> ret(arr, arr + sizeof(arr) / sizeof(*arr)); \
   return ret;})()

exemple de fonction

template<typename T>
void test(std::vector<T>& values)
{
    for(T value : values)
        std::cout<<value<<std::endl;
}

exemple d'utilisation

test(VECTOR(1.2f,2,3,4,5,6));

mais faites attention au decltype, assurez-vous que la première valeur correspond clairement à ce que vous voulez.

Josh
la source
3

Il existe différentes façons de coder en dur un vecteur, je vais partager quelques façons:

  1. Initialisation en poussant les valeurs une par une
// Create an empty vector 
    vector<int> vect;  

    vect.push_back(10); 
    vect.push_back(20); 
    vect.push_back(30); 
  1. Initialisation comme des tableaux
vector<int> vect{ 10, 20, 30 };
  1. Initialisation à partir d'un tableau
    int arr[] = { 10, 20, 30 }; 
    int n = sizeof(arr) / sizeof(arr[0]); 

    vector<int> vect(arr, arr + n); 
  1. Initialisation à partir d'un autre vecteur
    vector<int> vect1{ 10, 20, 30 }; 

    vector<int> vect2(vect1.begin(), vect1.end()); 
Anil Gupta
la source
2

"Comment créer un vecteur STL et l'initialiser comme ci-dessus? Quelle est la meilleure façon de le faire avec un effort de frappe minimal?"

La façon la plus simple d'initialiser un vecteur lorsque vous avez initialisé votre tableau intégré est d'utiliser une liste d'initialisation qui a été introduite en C ++ 11 .

// Initializing a vector that holds 2 elements of type int.
Initializing:
std::vector<int> ivec = {10, 20};


// The push_back function is more of a form of assignment with the exception of course
//that it doesn't obliterate the value of the object it's being called on.
Assigning
ivec.push_back(30);

ivec a 3 éléments après l'exécution de l'attribution (instruction étiquetée).

user2103487
la source
Dans les mêmes lignes, j'essaie d'initialiser la carte, std :: map <int, bool> catinfo = {{1, false}}; Mais alors obtenez cette erreur d'erreur: en C ++ 98 'catinfo' doit être initialisé par le constructeur, pas par '{...}'
pdk
2

B. Stroustrup décrit une belle façon de chaîner des opérations dans 16.2.10 Selfreference à la page 464 dans l'édition C ++ 11 du Prog. Lang. où une fonction renvoie une référence, ici modifiée en vecteur. De cette façon, vous pouvez enchaîner v.pb(1).pb(2).pb(3);mais peut être trop de travail pour de si petits gains.

#include <iostream>
#include <vector>

template<typename T>
class chain
{
private:
    std::vector<T> _v;
public:
    chain& pb(T a) {
        _v.push_back(a);
        return *this;
    };
    std::vector<T> get() { return _v; };
};

using namespace std;

int main(int argc, char const *argv[])
{
    chain<int> v{};

    v.pb(1).pb(2).pb(3);

    for (auto& i : v.get()) {
        cout << i << endl;
    }

    return 0;
}

1
2
3

kometen
la source
La bibliothèque armadillo fait cela pour l'initialisation de la matrice mais utilise l'opérateur << au lieu d'une fonction nommée: arma.sourceforge.net/docs.html#element_initialisation
Agnel Kurian
0

La manière la plus simple et la plus ergonomique (avec C ++ 11 ou version ultérieure):

auto my_ints = {1,2,3};
nz_21
la source
0

Au cas où vous voudriez l'avoir dans votre propre classe:

#include <initializer_list>
Vector<Type>::Vector(std::initializer_list<Type> init_list) : _size(init_list.size()),
_capacity(_size),
_data(new Type[_size])
{
    int idx = 0;
    for (auto it = init_list.begin(); it != init_list.end(); ++it)
        _data[idx++] = *it;
}
NixoN
la source