如何初始化“const std :: vector <T>”类似于ac数组
有没有一种优雅的方式来创build和初始化一个const std::vector<const T>
像const T a[] = { ... }
到一个固定的(和很小的)数值?
我需要经常调用一个函数,期望一个vector<T>
,但是这些值在我的情况下永远不会改变。
原则上我想到了类似的东西
namespace { const std::vector<const T> v(??); }
因为v不会在这个编译单元之外使用。
你要么等待C ++ 0x,要么使用类似Boost.Assign来做到这一点。
例如:
#include <boost/assign/std/vector.hpp> using namespace boost::assign; // bring 'operator+=()' into scope vector<int> v; v += 1,2,3,4,5;
对于C ++ 11:
vector<int> luggage_combo = { 1, 2, 3, 4, 5 };
如果你问如何初始化一个const向量,以便它有有趣的内容,那么答案可能是使用复制构造函数。 首先你费力地填写一个向量,然后你从它创build你的新的const向量。 或者,您可以使用vector<InputIterator>(InputIterator,InputIterator)构造函数模板从其他types的容器或数组中初始化。 如果是一个数组,那么可以用一个初始化列表来定义。
像这样的东西有希望接近你想要的东西:
const T ra[3] = {t1, t2, t3}; const vector<const T> v(ra, ra+3);
如果你问如何将一个const向量传递给一个带有向量的函数,那么答案是:
- 你不能,因为函数可能会改变向量,你的对象/引用是常量。 制作原始的非常量副本,并将其传入。
要么
- 使用const_cast来移除常量,以便将其传递给一个带有非常量向量的函数,但是您碰巧知道这个函数不会修改该向量。
后者是这样一种事情,它将会非常正确地让所有看到它的人对眼罩发表评论,以及他们什么也不做。 这正是const_cast的意思,但是有一个相当有力的论点,说如果你需要const_cast,你已经失去了。
做这两件事情(使用复制构造函数从非const构造一个const向量,然后抛出const)绝对是错误的 – 你应该只使用一个非const的向量。 所以select最多的一个做…
[编辑:只是注意到你正在谈论vector <T>和const vector <const T>之间的区别。 不幸的是,在STL中,vector <const T>和vector <T>是完全不相关的types,转换它们的唯一方法是复制。 这是向量和数组之间的区别 – 一个T **可以默默安全地转换为const T * const *]
简短和肮脏的方式(类似于Boost的list_of())
#include <iostream> #include <vector> #include <iterator> #include <algorithm> using namespace std; template <typename T> struct vlist_of : public vector<T> { vlist_of(const T& t) { (*this)(t); } vlist_of& operator()(const T& t) { this->push_back(t); return *this; } }; int main() { const vector<int> v = vlist_of<int>(1)(2)(3)(4)(5); copy(v.begin(), v.end(), ostream_iterator<int>(cout, "\n")); }
现在,C ++ 11有初始化列表,所以你不需要这样做,甚至使用Boost。 但是,作为一个例子,你可以像这样更有效地在C ++ 11中完成上述操作:
#include <iostream> #include <vector> #include <utility> #include <ostream> using namespace std; template <typename T> struct vlist_of : public vector<T> { vlist_of(T&& t) { (*this)(move(t)); } vlist_of& operator()(T&& t) { this->push_back(move(t)); return *this; } }; int main() { const vector<int> v = vlist_of<int>(1)(2)(3)(4)(5); for (const auto& i: v) { cout << i << endl; } }
但是,它仍然不如使用C ++ 11初始化程序列表那么有效,因为没有为vector定义的operator =(vlist_of &&)。
tjohns20的方式修改如下可能是一个更好的C ++ 11 vlist_of:
#include <iostream> #include <vector> #include <utility> using namespace std; template <typename T> class vlist_of { public: vlist_of(T&& r) { (*this)(move(r)); } vlist_of& operator()(T&& r) { v.push_back(move(r)); return *this; } vector<T>&& operator()() { return move(v); } private: vector<T> v; }; int main() { const auto v = vlist_of<int>(1)(2)(3)(4)(5)(); for (const auto& i : v) { cout << i << endl; } }
正如其他人所说的,你不能像初始化一个C风格的数组一样初始化一个向量,除非你给它指向一个源数组的指针。 但是在这种情况下,如果你的vector是一个全局常量,为什么不使用一个旧的C风格的数组呢?
const int MyInts[] = { 1, 2, 3, 4, 5}; const size_t NumMyInts = sizeof(MyInts)/sizeof(MyInts[0]);
你甚至可以对这个数组使用STLalgorithm,就像使用const vector的algorithm一样。
const int* myInt = std::find( &MyInts[0], &MyInts[NumMyInts], 3);
您可以分两步进行:
namespace { const T s_actual_array[] = { ... }; const std::vector<const T> s_blah(s_actual_array, s_actual_array + (sizeof(s_actual_array) / sizeof(s_actual_array[0]))); }
也许不像你可能喜欢的那样美丽,但function。
怎么样:
int ar[]={1,2,3,4,5,6}; const int TotalItems = sizeof(ar)/sizeof(ar[0]); std::vector<int> v(ar, ar+TotalItems);
老问题,但今天我遇到了同样的问题,这里是我的目的最可接受的方法:
vector<int> initVector(void) { vector<int> initializer; initializer.push_back(10); initializer.push_back(13); initializer.push_back(3); return intializer; } int main() { const vector<int> a = initVector(); return 0; }
避免过度复制的示例:
vector<int> & initVector(void) { static vector<int> initializer; if(initializer.empty()) { initializer.push_back(10); initializer.push_back(13); initializer.push_back(3); } return intializer; } int main() { const vector<int> & a = initVector(); return 0; }
不知道我是否理解你的权利。 我理解你的问题是这样的:你想将一个向量初始化为大量的元素。 在vector上使用push_back()有什么问题? 🙂
如果您知道要存储的元素的数量(或者确定它将存储小于下一个2的幂),则可以这样做,如果有一个Xtypes的指针向量(仅与指针一起工作):
std::vector< X* > v; v.reserve(num_elems); X* p = v.begin(); for (int count = 0; count < num_elems; count++) p[count] = some_source[count];
即使使用push_back(),也要注意添加2个以上的元素。 指向v.begin()的指针将无效。
如果他们都一样,你可以做
vector<T> vec(num_items, item);
但我认为他们不是 – 在这种情况下最好的方法可能是:
vector<T> vec(num_items); vec[0] = 15; vec[1] = 5; ...
C ++ 0x会让你按照你想的方式使用一个初始化列表,但不幸的是,现在不是很好。
基于Shadow2531的回应,我使用这个类来初始化向量,而不是像Shadow的解决scheme那样从std :: vectorinheritance
template <typename T> class vector_init { public: vector_init(const T& val) { vec.push_back(val); } inline vector_init& operator()(T val) { vec.push_back(val); return *this; } inline std::vector<T> end() { return vec; } private: std::vector<T> vec; };
用法:
std::vector<int> testVec = vector_init<int>(1)(2)(3)(4)(5).end();
与Steve Jessop的解决scheme相比,它创build了更多的代码,但是如果创build的数组不是性能关键的,我发现它是一个很好的方法来初始化一个数组