模板类中的许多方法都vector接受value_type对象的const引用,例如:
void push_back (const value_type& val);
Run Code Online (Sandbox Code Playgroud)
while 按值resize获取其value_type参数:
void resize (size_type n, value_type val = value_type());
Run Code Online (Sandbox Code Playgroud)
作为一个非专业的C++程序员,我只能想到这个选择的缺点(例如,如果size_of(value_type)可能发生足够大的堆栈溢出).因此,我想对那些对语言有更深入了解的人提出这样的要求:
这个选择背后的设计理由是什么?
假设我的矢量/列表中有30000个对象.我逐一添加.
我需要他们排序.
是否更快地一次性排序(如std :: sort),或者在逐个添加对象时保持向量/列表的排序?
向量/列表以后不会被修改.
我有C++代码,它声明了由函数调用初始化的静态生命周期变量.被调用的函数构造一个vector实例并调用其push_back方法.代码是否会冒险通过C++静态初始化命令惨败?如果没有,为什么不呢?
补充资料:
什么是"静态初始化命令惨败"?
为什么我认为使用vector会引发惨败?
vector构造函数可能会使用动态初始化的另一个静态生命周期变量的值.如果是这样,那么vector在我vector在代码中使用之前,没有什么可以确保变量被初始化.初始化result(参见下面的代码)可能会vector在vector完全初始化依赖项之前调用构造函数,从而导致访问未初始化的内存.
这段代码到底是什么样的?
struct QueryEngine {
QueryEngine(const char *query, string *result_ptr)
: query(query), result_ptr(result_ptr) { }
static void AddQuery(const char *query, string *result_ptr) {
if (pending == NULL)
pending = new vector<QueryEngine>;
pending->push_back(QueryEngine(query, result_ptr));
}
const char *query;
string *result_ptr;
static vector<QueryEngine> *pending;
};
vector<QueryEngine> *QueryEngine::pending = NULL;
void Register(const char *query, string *result_ptr) {
QueryEngine::AddQuery(query, result_ptr); …Run Code Online (Sandbox Code Playgroud)在下面的代码中,函数(foo)参数(std::vector)的大小可以是使函数成为通用函数的任何函数.但是,有时大小容器是已知的,因此可以使用std :: array.问题是转换std::array为std::vector.解决这个问题的最佳方法是什么?std::vector在这种情况下,总是使用总是更好吗?
#include <iostream>
#include <array>
#include <vector>
using namespace std;
// generic function: size of the container can be anything
void foo (vector<int>& vec)
{
// do something
}
int main()
{
array<int,3> arr; // size is known. why use std::vector?
foo (arr); // cannot convert std::array to std::vector
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我听说Modern C++的一个建议是使用emplace_back而不是push_back在容器中追加(emplace_back接受容器中任何类型存储的构造函数的任何版本的参数).
根据标准草案N3797 23.3.6.5(1),说:
备注:如果新大小大于旧容量,则会导致重新分配.如果没有重新分配,插入点之前的所有迭代器和引用仍然有效.如果除了复制构造函数之外抛出异常,移动构造函数,赋值运算符或T的移动赋值运算符,或者通过任何InputIterator操作都没有效果.如果非CopyInsertable T的移动构造函数抛出异常,则不指定效果.
这指定了在不需要重新分配时会发生什么,但在容器需要增长时保持打开问题.
在这段代码中:
#include <iostream>
#include <vector>
int main() {
std::vector<unsigned char> buff {1, 2, 3, 4};
buff.emplace_back(buff[0]);
buff.push_back(buff[1]);
for (const auto& c : buff) {
std::cout << std::hex << static_cast<long>(c) << ", ";
}
std::cout << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译VC++(Visual Studio的2013更新4)和GCC 4.9.1(MinGW的)在调试在Windows 8.1.
使用VC++编译时,输出为:
1, 2, 3, 4, dd, 2
Run Code Online (Sandbox Code Playgroud)
使用GCC编译时,输出为:
1, 2, 3, 4, 1, …Run Code Online (Sandbox Code Playgroud) 如何分配具有原子类型的向量成员?
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
int main()
{
vector<atomic<bool>> myvector;
int N=8;
myvector.assign(N,false);
cout<<"done!"<<endl;
}
Run Code Online (Sandbox Code Playgroud)
https://wandbox.org/permlink/lchfOvqyL3YKNivk
prog.cc: In function 'int main()':
prog.cc:11:28: error: no matching function for call to 'std::vector<std::atomic<bool> >::assign(int&, bool)'
11 | myvector.assign(N,false);
| ^
Run Code Online (Sandbox Code Playgroud) 根据cppreference.com和cplusplus.com,该函数std::erase(first, last)返回“最后一个删除元素之后的迭代器”。
但是,在完全没有被移除元素的特殊情况下,即当first == last(空范围)时,返回值是什么不清楚。截至 2020 年 1 月 19 日,上述消息来源均未提及此特殊情况。
例如,在以下代码中:
std::vector<int> v{1, 2, 3, 4};
auto it1 = v.erase(v.begin(), v.begin());
auto it2 = v.erase(v.end(), v.end());
Run Code Online (Sandbox Code Playgroud)
it1和的值是it2什么?
如何删除向量alphabets中与字符串中的任何字符匹配的元素plaintext?
这是我的尝试:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
//init
std::vector<std::string> alphabets{ "a", "b", "c", "d", "e", "f", "g", "h", "i", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
//input
std::string plaintext;
std::cout << "enter plain text: ";
std::cin >> plaintext;
for (std::string::iterator it = plaintext.begin(); it != plaintext.end(); it++)
{
std::vector<std::string>::iterator toErase;
toErase = std::find(alphabets.begin(), alphabets.end(), *it);
if (toErase != alphabets.end())
{ …Run Code Online (Sandbox Code Playgroud) 这更像是一个关于 C++ 的好奇问题,是在学习如何查找迭代器引用的索引后提出的。
给定两个向量迭代器,为什么它们可以相减但不能相加?
例如,为什么要编译和运行:
std::vector<int> vect;
vect.begin() - vect.end();
Run Code Online (Sandbox Code Playgroud)
虽然这不会:
std::vector<int> vect;
vect.begin() + vect.end();
Run Code Online (Sandbox Code Playgroud)
问题是更好地了解迭代器的行为方式。对于那些评论和回答的人,谢谢!我需要更多地研究指针算法才能理解这一点。
我认为最有帮助的答案是迭代器就像指针。
减去两个指针来得到它们的距离差是有道理的,就像在数轴上看 1-10 并想要 7 和 3 之间的距离,你从 3 中减去 7 得到 4 的距离。
将 7 和 3 相加得到 10,这并不能帮助我找到它们之间的距离,并且在容器中最终会指向容器边界之外的东西,这没有帮助或有用。
c++ iterator operator-overloading pointer-arithmetic stdvector
我有一个数组char* source和一个向量std::vector<char> target。我想让向量target指向sourceO(1),而不复制数据。
沿着这些路线的东西:
#include <vector>
char* source = new char[3] { 1, 2, 3 };
std::vector<char> target;
target.resize(3);
target.setData(source); // <- Doesn't exist
// OR
std::swap(target.data(), source); // <- swap() does not support char*
delete[] source;
Run Code Online (Sandbox Code Playgroud)
为什么不能手动更改矢量指向的位置?如果可能的话,是否会出现一些特定的、无法管理的问题?