What is the easiest way to initialize a std::vector with hardcoded elements?
我可以创建一个数组并像这样初始化它:
1 | int a[] = {10, 20, 30}; |
我如何创建一个
我知道最好的方法是:
1 2 3 4 5 | std::vector<int> ints; ints.push_back(10); ints.push_back(20); ints.push_back(30); |
有更好的方法吗?
如果你的编译器支持C++ 11,你可以简单地做:
1 | std::vector<int> v = {1, 2, 3, 4}; |
从4.4版起在GCC中提供。不幸的是,VC++2010在这方面似乎落后了。
或者,boost.assign库使用非宏魔术允许以下操作:
1 2 3 | #include <boost/assign/list_of.hpp> ... std::vector<int> v = boost::assign::list_of(1)(2)(3)(4); |
或:
1 2 3 4 5 | #include <boost/assign/std/vector.hpp> using namespace boost::assign; ... std::vector<int> v; v += 1, 2, 3, 4; |
但请记住,这有一些开销(基本上,
一种方法是使用数组初始化向量
1 2 | static const int arr[] = {16,2,77,29}; vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) ); |
在C++0x中,您将能够以与数组相同的方式来完成它,但不能在当前标准中执行。
只有语言支持才能使用:
1 2 | int tmp[] = { 10, 20, 30 }; std::vector<int> v( tmp, tmp+3 ); // use some utility to avoid hardcoding the size here |
如果可以添加其他库,可以尝试boost::assignment:
1 | vector<int> v = list_of(10)(20)(30); |
要避免硬编码数组的大小,请执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 | // 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)) |
(P)如果你能,用现代C+[11,14,17,…]方式:(p)字母名称(P)The old way of looping over a variable-Length array or using EDOCX1 commercial 4-is truly terrible on the eyes and completely unnecessary in terms of mental overhead.Yuck.(p)
在C++ 11中:
1 2 3 4 5 6 | #include <vector> using std::vector; ... vector<int> vec1 { 10, 20, 30 }; // or vector<int> vec2 = { 10, 20, 30 }; |
使用以下增强列表:
1 2 3 4 5 | #include <vector> #include <boost/assign/list_of.hpp> using std::vector; ... vector<int> vec = boost::assign::list_of(10)(20)(30); |
使用增强分配:
1 2 3 4 5 6 | #include <vector> #include <boost/assign/std/vector.hpp> using std::vector; ... vector<int> vec; vec += 10, 20, 30; |
传统STL:
1 2 3 4 5 | #include <vector> using std::vector; ... static const int arr[] = {10,20,30}; vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) ); |
带通用宏的传统STL:
1 2 3 4 5 6 7 | #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:
1 2 3 4 5 6 | #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); |
我只是想把我的0.02美元投进去。我倾向于声明:
1 2 3 4 5 | template< typename T, size_t N > std::vector<T> makeVector( const T (&data)[N] ) { return std::vector<T>(data, data+N); } |
在某个实用程序头中,需要的只是:
1 2 | const double values[] = { 2.0, 1.0, 42.0, -7 }; std::vector<double> array = makeVector(values); |
但是我不能等待C++0X。我被困了,因为我的代码也必须在VisualStudio中编译。喝倒采。
(P)before C++11:(p)(P)方法1=(p)字母名称(P)方法2=(p)字母名称(P)C++11 onward below is also possible(p)字母名称
从:
1 | int a[] = {10, 20, 30}; //i'm assuming a is just a placeholder |
如果你没有一个C++ 11编译器,那么你就不想使用Booost:
1 2 | 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编译器,可以使用Booost:
1 2 | #include <boost/assign.hpp> const std::vector<int> ints = boost::assign::list_of(10)(20)(30); |
如果你有一个C++ 11编译器:
1 | const std::vector<int> ints = {10,20,30}; |
最简单的方法是:
1 | vector<int> ints = {10, 20, 30}; |
(P)For vector initialisation-(p)字母名称(P)如果你有C++11竞争对手,你可以成为礼物。(p)(P)Else,you can have an array of the data and they use a for loop.(p)字母名称(P)Apart from these,there are various other ways described above using some code.在我看来,这些方式很容易记起来,而且很容易写下来。(p)
如果编译器支持variadic宏(对于大多数现代编译器都是如此),则可以使用以下宏将矢量初始化转换为一行程序:
1 2 3 | #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)) |
使用此宏,您可以使用如下代码定义初始化向量:
1 | INIT_VECTOR(int, my_vector, {1, 2, 3, 4}); |
这将创建一个名为my_vector的ints新向量,元素为1、2、3、4。
如果你不想使用boost,但想享受类似于
1 2 | std::vector<int> v; v+=1,2,3,4,5; |
只包括这段代码
1 2 3 4 5 6 7 8 9 | 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; } |
我使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #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; } |
演示
在C++ 11中:
1 2 | static const int a[] = {10, 20, 30}; vector<int> vec (begin(a), end(a)); |
最近的一个重复的问题得到了维克多·瑟尔的回答。对我来说,它是紧凑的、视觉上吸引人的(看起来像是在推挤值),不需要C++ 11或第三方模块,并且避免使用额外的(书面的)变量。下面是我如何使用它并做一些更改。我可以在以后的集成中切换到扩展向量和/或va_arg的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // 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) |
您可以使用boost::assign来实现这一点。
1 2 | vector<int> values; values += 1,2,3,4,5,6,7,8,9; |
这里详细
(P)Below methods can be used to initialize the vector in C++。(p)
(P)The third one is allowed only in C++11 onwards.(p)
(P)有一个很好的答案在这里,但自从我独立地来到我自己的地方之前,我figured I'd toss mine up here anyway…(p)(P)这里的一种方法是,我将使用这一方法,这将是一个普遍性的工作,参加者和平台:(p)(P)创建一个结构或类别作为一个容器,以收集你的目标。定义一个超值操作函数。(p)字母名称(P)You can create functions which take your structure as a parameter,e.g.:(p)字母名称(P)Then,you can call that function,like this:(p)字母名称(P)That way,you can build and pass a dynamically sized collection of objects to a function in one single clean line!(p)
如果需要与boost::assign具有相同常规顺序的内容,而不创建对boost的依赖关系,则以下内容至少类似:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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); } |
虽然我希望使用它的语法更清晰,但它仍然不是特别糟糕:
1 | std::vector<int> x = (makeVect(1), 2, 3, 4); |
字母名称
(P)If the array is:(p)字母名称
1 2 3 | typedef std::vector<int> arr; arr a {10, 20, 30}; // This would be how you initialize while defining |
编译使用:
1 | clang++ -std=c++11 -stdlib=libc++ <filename.cpp> |
相关的,如果您想要一个向量完全准备好进入一个快速语句(例如,立即传递到另一个函数),则可以使用以下方法:
1 2 3 4 5 | #define VECTOR(first,...) \ ([](){ \ static const decltype(first) arr[] = { first,__VA_ARGS__ }; \ std::vector<decltype(first)> ret(arr, arr + sizeof(arr) / sizeof(*arr)); \ return ret;})() |
示例函数
1 2 3 4 5 6 | template<typename T> void test(std::vector<T>& values) { for(T value : values) std::cout<<value<<std::endl; } |
例用
1 | test(VECTOR(1.2f,2,3,4,5,6)); |
尽管要注意decltype,但要确保第一个值是您想要的。
"如何创建一个STL向量并像上面那样初始化它?用最少的打字工作量,最好的方法是什么?"
初始化初始化数组时最简单的方法是使用在C++ 11中引入的初始化列表。
1 2 3 4 5 6 7 8 9 | // 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个元素。
(P)b.Stroustrup describines a nice way to chain operations in 16.2.10 selfreference on page 464 in the C++11 edition of the prog.Lang.Where a function returns a reference,here modified to a vector.这个方法你可以像EDOCX1一样,发音0,但它可能是太多的工作为这些小的性别。(p)字母名称布尔奇1