I se poate crea o matrice și inițializează astfel:
int a[] = {10, 20, 30};
Cum pot crea un std::vector și inițializa în mod similar elegant?
Cel mai bun mod de stiu este:
std::vector<int> ints;
ints.push_back(10);
ints.push_back(20);
ints.push_back(30);
Există o modalitate mai bună?
Dacă compiler susține C++11, puteți face pur și simplu:
std::vector<int> v = {1, 2, 3, 4};
Acesta este disponibil în GCC ca de versiunea 4.4. Din păcate, VC++ 2010 pare să fi rămas în urmă în acest sens.
Alternativ, Boost.Assign biblioteca utilizează non-macro magic pentru a permite următoarele:
#include <boost/assign/list_of.hpp>
...
std::vector<int> v = boost::assign::list_of(1)(2)(3)(4);
Sau:
#include <boost/assign/std/vector.hpp>
using namespace boost::assign;
...
std::vector<int> v;
v += 1, 2, 3, 4;
Dar țineți minte că acest lucru are unele deasupra capului (de fapt, list_of
construiește un std::deque` sub capota) deci pentru performanță critice cod'd fi mai bine ca Yacoby spune.
Dacă puteți, folosiți modern C++[11,14,17,...] mod:
std::vector<int> vec = {10,20,30};
Vechiul mod de looping pe o lungime variabilă array sau folosind sizeof()
este adevărat teribil pe ochi și complet inutile din punct de vedere mental deasupra capului. Yuck.
În C++0x va fi capabil să-l facă în același mod în care ai făcut-o cu o matrice, dar nu la standardul actual.
Cu doar limba suport se pot utiliza:
int tmp[] = { 10, 20, 30 };
std::vector<int> v( tmp, tmp+3 ); // use some utility to avoid hardcoding the size here
Dacă puteți adăuga alte biblioteci ai putea încerca boost::misiune:
vector<int> v = list_of(10)(20)(30);
Pentru a evita hardcoding dimensiunea unei matrice:
// 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))
În C++11:
#include <vector>
using std::vector;
...
vector<int> vec1 { 10, 20, 30 };
// or
vector<int> vec2 = { 10, 20, 30 };
Folosind impuls list_of:
#include <vector>
#include <boost/assign/list_of.hpp>
using std::vector;
...
vector<int> vec = boost::assign::list_of(10)(20)(30);
Folosind impuls atribui:
#include <vector>
#include <boost/assign/std/vector.hpp>
using std::vector;
...
vector<int> vec;
vec += 10, 20, 30;
Convenționale STL:
#include <vector>
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
Convenționale STL cu generic macro-uri:
#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));
Convenționale STL cu un vector de inițializare macro:
#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);
Doar crezut că am'd aruncă în $0.02. Eu tind să declare acest lucru:
template< typename T, size_t N >
std::vector<T> makeVector( const T (&data)[N] )
{
return std::vector<T>(data, data+N);
}
într-o utilitate antet undeva și apoi toate ca's necesar este:
const double values[] = { 2.0, 1.0, 42.0, -7 };
std::vector<double> array = makeVector(values);
Dar nu pot't așteptați pentru C++0x. Am'm-a blocat pentru că mi-cod trebuie, de asemenea, compila în Visual Studio. Boo.
Înainte De C++ 11 :
Metoda 1=>
vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));
vector<int>v;
Metoda 2 =>
v.push_back(SomeValue);
C++ 11 înainte de mai jos este, de asemenea, posibil
vector<int>v = {1, 3, 5, 7};
Incepand cu:
int a[] = {10, 20, 30}; //i'm assuming a is just a placeholder
Dacă tu nu't au un C++11 compiler și don't doriți să utilizați boost:
const int a[] = {10, 20, 30};
const std::vector<int> ints(a,a+sizeof(a)/sizeof(int)); //make it const if you can
Dacă tu nu't au un C++11 compilator și poate folosi boost:
#include <boost/assign.hpp>
const std::vector<int> ints = boost::assign::list_of(10)(20)(30);
Dacă aveți un C++11 compiler:
const std::vector<int> ints = {10,20,30};
Pentru vector de inițializare -
vector<int> v = {10,20,30}
poate fi făcut dacă ai fi c++11 compiler.
Altfel, poti avea o serie de date și apoi utilizați-o pentru buclă.
int array[] = {10,20,30}
for(unsigned int i=0; i<sizeof(array)/sizeof(array[0]); i++)
{
v.push_back(array[i]);
}
În afară de acestea, există numeroase alte modalități descrise mai sus, folosind un cod. În opinia mea, aceste moduri sunt ușor să vă amintiți și rapid de a scrie.
Dacă compiler sprijină Variadic macro (ceea ce este adevărat pentru cele mai moderne compilatoare), atunci puteți folosi următoarele macro la rândul său vector de inițializare într-o singură linie:
#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))
Cu acest macro, puteți defini un vector initializat cu cod de genul:
INIT_VECTOR(int, my_vector, {1, 2, 3, 4});
Acest lucru ar crea un nou vector de int numit my_vector cu elementele 1, 2, 3, 4.
Voi construi propria mea soluție folosind va_arg
. Această soluție este C++98 conforme.
#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;
}
Dacă tu nu't doriți să utilizați impuls, dar vrei să bucurați-vă de sintaxă ca
std::vector<int> v;
v+=1,2,3,4,5;
includ doar bucata asta de cod
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;
}
O mai recentă chestiune duplicat a acest răspuns de către Viktor Sehr. Pentru mine, este compact, atrăgător (arata ca tine sunt 'impingandu - ' valorile in), nu't nevoie de c++11 sau o terță parte modul, și evită să folosească un plus (scris) variabilă. Mai jos este cum de eu sunt, folosind cu câteva modificări. Am putea trece la extinderea funcție de vector și/sau va_arg în viitor 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)
Mai jos metode pot fi folosite pentru a inițializa vector in c++.
int arr[] = {1, 3, 5, 6}; vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));
`vector
vector<int>v = {1, 3, 5, 7};
Cea de a treia este permisă numai în C++11-lea.
// 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.
Daca vrei ceva pe aceeași general pentru ca Boost::atribuirea fără a crea o dependență pe Impuls, următoarele este cel puțin vag similare:
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);
}
În timp ce îmi doresc sintaxa pentru utilizarea acestuia a fost curat, l's încă nu deosebit de groaznic:
std::vector<int> x = (makeVect(1), 2, 3, 4);
Există o mulțime de răspunsuri bune aici, dar când am ajuns în mod independent la propria mea înainte de a citi acest lucru, m-am gândit'd aruncare a mea aici...
Aici's o metoda pe care am'm, folosind pentru acest lucru, care va lucra universal peste compilatoare și platforme:
A crea o struct sau class ca un container pentru o colecție de obiecte. A defini un operator de suprasarcină funcție de <<.
class MyObject;
struct MyObjectList
{
std::list<MyObject> objects;
MyObjectList& operator<<( const MyObject o )
{
objects.push_back( o );
return *this;
}
};
Puteți crea funcții care ia struct ca un parametru, de exemplu:
someFunc( MyObjectList &objects );
Apoi, puteți apela această funcție, astfel:
someFunc( MyObjectList() << MyObject(1) << MyObject(2) << MyObject(3) );
În acest fel, puteți construi și de a trece la un mod dinamic de dimensiuni colecție de obiecte la o funcție într-o singură linie curată!