用硬编码元素初始化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::deque
在list_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。
-
int arr[] = {1, 3, 5, 6}; vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));
-
vector<int>v; v.push_back(1); v.push_back(2); v.push_back(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