用硬编码元素初始化std :: vector最简单的方法是什么?

我可以创build一个数组,并像这样初始化它:

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

如何创build一个std::vector并初始化它类似的优雅?

我知道的最好的方法是:

 std::vector<int> ints; ints.push_back(10); ints.push_back(20); ints.push_back(30); 

有没有更好的办法?

一种方法是使用数组来初始化向量

 static const int arr[] = {16,2,77,29}; vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) ); 

如果你的编译器支持C ++ 11,你可以简单地做:

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

这在4.4版本的 GCC中可用。 不幸的是,VC ++ 2010在这方面似乎落后了。

或者, Boost.Assign库使用非macros魔法来允许以下内容:

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

要么:

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

但请记住,这有一些开销(基本上, list_of构build了一个std::dequelist_of ),所以对于性能关键的代码,你最好不要像Yacoby说的那样做。

在C ++ 0x中,你将能够以与你使用数组相同的方式来完成,而不是在当前的标准中。

只有语言支持,您可以使用:

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

如果你可以添加其他库,你可以尝试boost :: assignment:

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

为了避免硬编码数组的大小:

 // 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)) 

只是以为我会在0.02美元折腾。 我倾向于声明:

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

在一个实用程序标题的地方,然后所需的是:

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

但我不能等待C ++ 0x。 我卡住了,因为我的代码也必须在Visual Studio中编译。 嘘。

在C ++ 11中:

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

使用boost list_of:

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

使用boost分配:

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

常规STL:

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

使用genericsmacros的传统STL:

 #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)); 

使用向量初始化macros的常规STL:

 #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); 

在C ++ 11之前:

方法1 =>

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

方法2 =>

  v.push_back(SomeValue); 

C ++ 11以下也是可以的

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

从…开始:

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

如果您没有C ++ 11编译器,而您又不想使用boost:

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

如果你没有C ++ 11编译器,可以使用boost:

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

如果你有一个C ++ 11编译器:

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

最简单的方法是:

 vector<int> ints = {10, 20, 30}; 

如果您的编译器支持可变参数macros (对于大多数现代编译器都是如此),那么您可以使用以下macros将向量初始化转换为一行:

 #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)) 

有了这个macros,你可以用这样的代码定义一个初始化的向量:

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

这将创build一个名为my_vector的inttypes的元素1,2,3,4的新向量。

如果你不想使用提升,但想要享受类似的语法

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

只是包括这块代码

 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; } 

你可以使用boost :: assign来做到这一点。

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

细节在这里

在C ++ 11中:

 static const int a[] = {10, 20, 30}; vector<int> vec (begin(a), end(a)); 

我使用va_arg构build自己的解决scheme。 该解决scheme符合C98。

 #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; } 

演示

Viktor Sehr 回答了最近的一个重复问题。 对我来说,它是紧凑的,在视觉上吸引人的(看起来就像是“推倒”的值),不需要c ++ 11或第三方模块,并避免使用额外的(写入)variables。 以下是我如何使用它的一些变化。 我可能会切换到扩展向量和/或va_arg函数在未来的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) 

vector初始化 –

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

可以做,如果你有C + + 11编译器。

否则,你可以有一个数组的数据,然后使用for循环。

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

除了这些之外,还有使用一些代码的上述各种其他方式。 在我看来,这些方法很容易记住,而且写得很快。

下面的方法可以用来在c ++中初始化vector。

  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); 等等

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

第三个只允许在C ++ 11以上。

如果你想在Boost :: assign的同样的一般顺序上,而不是在Boost上创build一个依赖关系,那么下面至less有一些类似的含义:

 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); } 

虽然我希望使用它的语法更清晰,但仍然不是特别糟糕:

 std::vector<int> x = (makeVect(1), 2, 3, 4); 
 typedef std::vector<int> arr; arr a {10, 20, 30}; // This would be how you initialize while defining 

编译使用:

 clang++ -std=c++11 -stdlib=libc++ <filename.cpp> 

这里有很多很好的答案,但是因为我在读这本书之前独立自主地到达了这里,所以我想我还是会把它扔在这里。

下面是一个我正在使用的方法,这个方法可以在编译器和平台上普遍使用:

创build一个结构或类作为您的对象集合的容器。 为<<定义一个运算符重载函数。

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

你可以创build把你的结构作为参数的函数,例如:

 someFunc( MyObjectList &objects ); 

然后,你可以调用这个函数,像这样:

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

这样,你可以build立一个dynamic的大小的对象集合在一个简单的行中传递给一个函数!

 // 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. 

我看到如果数组是:

 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 

“我如何创build一个STL向量并像上面那样初始化它?用最less的打字工作,最好的方法是什么?

初始化内置数组的初始化vector的最简单方法是使用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的大小是3个元素。

相关的,如果你想让一个vector完全准备好进入一个快速的语句(例如,立即传递给另一个函数),你可以使用下面的代码:

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

示例函数

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

示例使用

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

虽然要小心decltype,确保第一个值显然是你想要的。

B. Stroustrup描述了在Prog的C ++ 11版本中的一个很好的链接16.2.10自引用的方法。 郎。 函数返回一个引用,这里修改为一个向量。 这样你可以链接像v.pb(1).pb(2).pb(3); 但是这么小的收益可能太多了。

 #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