Saya dapat membuat dan menginisialisasi sebuah array seperti ini:
int a[] = {10, 20, 30};
Bagaimana cara membuat std::vektor
dan menginisialisasi demikian pula elegan?
Cara terbaik yang saya tahu adalah:
std::vector<int> ints;
ints.push_back(10);
ints.push_back(20);
ints.push_back(30);
Apakah ada cara yang lebih baik?
Jika anda compiler mendukung C++11, anda hanya dapat melakukan:
std::vector<int> v = {1, 2, 3, 4};
Ini tersedia dalam GCC sebagai versi 4.4. Sayangnya, VC++ 2010 tampaknya akan tertinggal dalam hal ini.
Atau, Boost.Menetapkan perpustakaan menggunakan non-macro magic untuk memungkinkan hal berikut:
#include <boost/assign/list_of.hpp>
...
std::vector<int> v = boost::assign::list_of(1)(2)(3)(4);
Atau:
#include <boost/assign/std/vector.hpp>
using namespace boost::assign;
...
std::vector<int> v;
v += 1, 2, 3, 4;
Namun perlu diingat bahwa hal ini memiliki beberapa overhead (pada dasarnya, list_of
membangun std::deque
di bawah kap mesin) jadi untuk kinerja-kritis code anda'a akan lebih baik lakukan seperti yang Yacoby kata.
Jika anda bisa, menggunakan modern C++[11,14,17,...] cara:
std::vector<int> vec = {10,20,30};
Cara lama perulangan lebih dari panjang variabel array atau menggunakan sizeof()
ini benar-benar mengerikan pada mata dan benar-benar tidak perlu dalam hal mental overhead. Yuck.
Dalam C++0x anda akan dapat melakukannya dengan cara yang sama yang anda lakukan dengan array, tapi tidak dalam standar saat ini.
Hanya dengan dukungan bahasa yang dapat anda gunakan:
int tmp[] = { 10, 20, 30 };
std::vector<int> v( tmp, tmp+3 ); // use some utility to avoid hardcoding the size here
Jika anda dapat menambahkan perpustakaan lain anda bisa mencoba meningkatkan::tugas:
vector<int> v = list_of(10)(20)(30);
Untuk menghindari hardcoding ukuran array:
// 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))
Dalam C++11:
#include <vector>
using std::vector;
...
vector<int> vec1 { 10, 20, 30 };
// or
vector<int> vec2 = { 10, 20, 30 };
Menggunakan boost list_of:
#include <vector>
#include <boost/assign/list_of.hpp>
using std::vector;
...
vector<int> vec = boost::assign::list_of(10)(20)(30);
Menggunakan boost menetapkan:
#include <vector>
#include <boost/assign/std/vector.hpp>
using std::vector;
...
vector<int> vec;
vec += 10, 20, 30;
Konvensional STL:
#include <vector>
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
Konvensional STL dengan generic macro:
#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));
Konvensional STL dengan vektor penginisialisasi makro:
#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);
Hanya pikir saya'd melemparkan my $0.02. Saya cenderung menyatakan ini:
template< typename T, size_t N >
std::vector<T> makeVector( const T (&data)[N] )
{
return std::vector<T>(data, data+N);
}
dalam sebuah utilitas header di suatu tempat dan kemudian semua yang's yang dibutuhkan adalah:
const double values[] = { 2.0, 1.0, 42.0, -7 };
std::vector<double> array = makeVector(values);
Tapi aku bisa't menunggu untuk C++0x. I'm terjebak karena kode saya juga harus mengkompilasi dalam Visual Studio. Boo.
Sebelum C++ 11 :
Metode 1=>
vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));
vector<int>v;
Metode 2 =>
v.push_back(SomeValue);
C++ 11 selanjutnya berikut ini juga mungkin
vector<int>v = {1, 3, 5, 7};
Dimulai dengan:
int a[] = {10, 20, 30}; //i'm assuming a is just a placeholder
Jika anda don't memiliki C++11 compiler dan anda don't ingin menggunakan boost:
const int a[] = {10, 20, 30};
const std::vector<int> ints(a,a+sizeof(a)/sizeof(int)); //make it const if you can
Jika anda don't memiliki C++11 compiler dan dapat menggunakan boost:
#include <boost/assign.hpp>
const std::vector<int> ints = boost::assign::list_of(10)(20)(30);
Jika anda memiliki C++11 compiler:
const std::vector<int> ints = {10,20,30};
Untuk vektor inisialisasi -
vector<int> v = {10,20,30}
dapat dilakukan jika anda memiliki compiler c++11.
Yang lain, anda dapat memiliki sebuah array dari data dan kemudian menggunakan loop for.
int array[] = {10,20,30}
for(unsigned int i=0; i<sizeof(array)/sizeof(array[0]); i++)
{
v.push_back(array[i]);
}
Selain ini, ada berbagai cara lain yang dijelaskan di atas menggunakan beberapa kode. Dalam pendapat saya, ini cara yang mudah untuk diingat dan cepat untuk menulis.
Jika anda compiler mendukung Variadic macro (yang berlaku untuk paling modern compiler), maka anda dapat menggunakan makro berikut untuk mengubah vektor inisialisasi menjadi satu-liner:
#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))
Dengan makro ini, anda dapat menentukan inisialisasi vektor dengan kode seperti ini:
INIT_VECTOR(int, my_vector, {1, 2, 3, 4});
Hal ini akan menciptakan sebuah vektor baru int bernama my_vector dengan elemen 1, 2, 3, 4.
Saya membangun sendiri solusi menggunakan va_arg
. Solusi ini adalah C++98 compliant.
#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;
}
Jika anda don't ingin menggunakan boost, tapi ingin menikmati sintaks seperti
std::vector<int> v;
v+=1,2,3,4,5;
hanya seperti ini potongan 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;
}
Yang lebih baru duplikat pertanyaan yang telah jawaban ini oleh Viktor Sehr. Bagi saya, hal ini kompak, menarik secara visual (terlihat seperti anda 'mendorong' nilai-nilai dalam), doesn't membutuhkan c++11 atau pihak ketiga modul, dan menghindari menggunakan aplikasi tambahan (tertulis) variabel. Di bawah ini adalah cara yang saya gunakan itu dengan beberapa perubahan. Aku dapat beralih untuk memperluas fungsi vektor dan/atau va_arg di masa depan 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)
Berikut metode yang dapat digunakan untuk inisialisasi vektor dalam c++.
int arr[] = {1, 3, 5, 6}; vektor<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));
vektor<int>v; v. push_back(1); v. push_back(2); v. push_back(3);
dan sebagainya
vektor<int>v = {1, 3, 5, 7};
Yang ketiga adalah diperbolehkan hanya dalam C++11 dan seterusnya.
// 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.
Jika anda ingin sesuatu yang umum yang sama guna sebagai Boost::menetapkan tanpa menciptakan ketergantungan pada Boost, berikut adalah setidaknya samar-samar mirip:
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);
}
Sementara saya berharap sintaks untuk menggunakan itu bersih, itu's masih tidak terlalu mengerikan:
std::vector<int> x = (makeVect(1), 2, 3, 4);
Ada banyak jawaban yang baik di sini, tapi karena saya independen tiba di saya sendiri sebelum membaca ini, saya pikir saya'd melemparkan saya ke sini pula...
Berikut ini's metode yang saya'm menggunakan untuk ini yang akan bekerja secara universal di seluruh compiler dan platform:
Membuat struct atau kelas sebagai wadah untuk koleksi anda dari benda-benda. Mendefinisikan operator overload fungsi untuk <<.
class MyObject;
struct MyObjectList
{
std::list<MyObject> objects;
MyObjectList& operator<<( const MyObject o )
{
objects.push_back( o );
return *this;
}
};
Anda dapat menciptakan fungsi-fungsi yang mengambil struct anda sebagai parameter, misalnya:
someFunc( MyObjectList &objects );
Kemudian, anda dapat memanggil fungsi itu, seperti ini:
someFunc( MyObjectList() << MyObject(1) << MyObject(2) << MyObject(3) );
Dengan cara itu, anda dapat membangun dan lulus dinamis berukuran koleksi benda-benda ke fungsi dalam satu garis yang bersih!