我有一个应用程序正在对某些图像执行某些处理.
鉴于我知道宽度/高度/格式等(我这样做),并考虑定义一个缓冲区来存储像素数据:
然后,而不是使用new与delete []上unsigned char*并保持一个单独的说明缓冲区大小的,我想通过使用简化的事情std::vector.
所以我会宣布我的课程是这样的:
#include <vector>
class MyClass
{
// ... etc. ...
public:
virtual void OnImageReceived(unsigned char *pPixels,
unsigned int uPixelCount);
private:
std::vector<unsigned char> m_pImageBuffer; // buffer for 8-bit pixels
// ... etc. ...
};
Run Code Online (Sandbox Code Playgroud)
然后,当我收到一个新图像(一些可变大小 - 但不要担心这些细节)时,我可以调整矢量大小(如果需要)并复制像素:
void MyClass::OnImageReceived(unsigned char *pPixels, unsigned int uPixelCount)
{
// called when a new image is available
if (m_pImageBuffer.size() != uPixelCount)
{
// resize image buffer
m_pImageBuffer.reserve(uPixelCount);
m_pImageBuffer.resize(uPixelCount, 0);
}
// copy …Run Code Online (Sandbox Code Playgroud) 我今天和我的同事想知道是否可以实现std :: vector来利用小缓冲区优化.通过查看C++ 11草案,我在23.3.1p8阅读
表达式a.swap(b),对于除数组之外的标准容器类型的容器a和b,应交换a和b的值,而不对单个容器元素调用任何移动,复制或交换操作.
这开始似乎取决于小缓冲区优化,但在as-if规则下,我们将被允许仍然对非类类型进行小缓冲区优化(因为我们无法观察到正在完成的复制).下一个文字似乎更难"傻瓜"
在交换之前引用一个容器中的元素的每个迭代器应该在交换之后引用另一个容器中的相同元素.
这是否足以阻止为std :: vector实现小缓冲区优化?有没有其他的路障或最终有可能有SBO的std :: vector?
我有两个STL向量A,B并且我想清除所有元素A并将所有元素移动B到A然后清除B.简单地说,我想这样做:
std::vector<MyClass> A;
std::vector<MyClass> B;
....
A = B;
B.clear();
Run Code Online (Sandbox Code Playgroud)
因为B可能很长,所以需要k*O(N)执行此操作,其中k是常量,并且N是max(size_of(A), size_of(B)).我想知道是否有更有效的方法可以做到这一点.我能想到的一件事是定义A和B作为指针,然后在恒定时间内复制指针并清除B.
我正在做一些测试,测量标准容器在各种条件下的性能,我遇到了一些奇怪的事情.当我将许多项目进入的中间std::vector,如果我首先调用储备与我会加入元素的确切数目,我看基本上是在大多数情况下没有性能上的差异与不调用储备,这是令人惊讶的对比.然而,更令人惊讶的是,如果我使用我需要的确切数量的元素来调用reserve + 1,那么我将获得显着的性能提升.这是我刚收到的结果示例表(所有时间都以秒为单位):
+---------------+--------+-------------------+-----------------------+
| # of elements | vector | vector (reserved) | vector (reserved + 1) |
+---------------+--------+-------------------+-----------------------+
| 10000 | 0.04 | 0.04 | 0.03 |
| 20000 | 0.14 | 0.14 | 0.11 |
| 30000 | 0.32 | 0.32 | 0.25 |
| 40000 | 0.55 | 0.55 | 0.44 |
| 50000 | 0.87 | 0.85 | 0.66 |
| 60000 | 1.24 | 1.24 | 0.96 |
| 70000 | …Run Code Online (Sandbox Code Playgroud) 任何人都可以解释一下记忆的布局
std::vector<std::array<int, 5>> vec(2)
Run Code Online (Sandbox Code Playgroud)
它是否提供具有2行5个元素的2D数组的连续内存块?
据我所知,矢量矢量
std::vector<std::vector<int>> vec(2, std::vector<int>(5))
Run Code Online (Sandbox Code Playgroud)
提供存储器中不同位置的两个 长度为 5个元素的连续数组的存储器布局.
对于数组的向量是否相同?
我有一个采用多维的函数,std::vector并需要将深度(或维数)作为模板参数传入。我不想对这个值进行硬编码,我想编写一个constexpr函数,它将std::vector深度作为unsigned integer值返回。
例如:
std::vector<std::vector<std::vector<int>>> v =
{
{ { 0, 1}, { 2, 3 } },
{ { 4, 5}, { 6, 7 } },
};
// Returns 3
size_t depth = GetDepth(v);
Run Code Online (Sandbox Code Playgroud)
这需要在编译时完成,因为这个深度将作为模板参数传递给模板函数:
// Same as calling foo<3>(v);
foo<GetDepth(v)>(v);
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?
考虑以下片段:
#include <array>
int main() {
using huge_type = std::array<char, 20*1024*1024>;
huge_type t;
}
Run Code Online (Sandbox Code Playgroud)
显然它会在大多数平台上崩溃,因为默认堆栈大小通常小于 20MB。
现在考虑以下代码:
#include <array>
#include <vector>
int main() {
using huge_type = std::array<char, 20*1024*1024>;
std::vector<huge_type> v(1);
}
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是它也崩溃了!回溯(使用最近的 libstdc++ 版本之一)指向include/bits/stl_uninitialized.h文件,我们可以在其中看到以下几行:
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
std::fill(__first, __last, _ValueType());
Run Code Online (Sandbox Code Playgroud)
调整大小vector构造函数必须默认初始化元素,这就是它的实现方式。显然,_ValueType()临时会导致堆栈崩溃。
问题是它是否是一个符合要求的实现。如果是,那实际上意味着大类型向量的使用非常有限,不是吗?
我需要在一个向量中存储多种类型的模板类.
例如,对于:
template <typename T>
class templateClass{
bool someFunction();
};
Run Code Online (Sandbox Code Playgroud)
我需要一个存储所有的向量:
templateClass<int> t1;
templateClass<char> t2;
templateClass<std::string> t3;
etc
Run Code Online (Sandbox Code Playgroud)
据我所知这是不可能的,如果有人可以说怎么样?
如果不可能有人解释如何进行以下工作?
作为一种解决方法,我尝试使用基本的非模板类并从中继承模板类.
class templateInterface{
virtual bool someFunction() = 0;
};
template <typename T>
class templateClass : public templateInterface{
bool someFunction();
};
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个向量来存储基础"templateInterface"类:
std::vector<templateInterface> v;
templateClass<int> t;
v.push_back(t);
Run Code Online (Sandbox Code Playgroud)
这产生了以下错误:
error: cannot allocate an object of abstract type 'templateInterface'
note: because the following virtual functions are pure within 'templateInterface'
note: virtual bool templateInterface::someFunction()
Run Code Online (Sandbox Code Playgroud)
为了解决这个错误,我在templateInterface中使函数不是一个纯虚拟的,通过提供一个函数体,这个编译但是在调用函数时不使用overide,而是在虚函数中使用body.
例如:
class templateInterface{
virtual bool someFunction() {return true;}
}; …Run Code Online (Sandbox Code Playgroud) 我想知道是否存在初始化静态向量的"更好"方式而不是下面的方法?
class Foo
{
static std::vector<int> MyVector;
Foo()
{
if (MyVector.empty())
{
MyVector.push_back(4);
MyVector.push_back(17);
MyVector.push_back(20);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个示例代码:)
push_back()中的值是独立声明的; 不是数组或其他东西.
编辑:如果不可能,告诉我也:)
这可能是一个愚蠢的问题,我对C++和编程很新.我想了解几个STL容器的使用,考虑到这一点,我想知道使用std :: set vs使用矢量或地图的优点是什么?我似乎无法找到这个问题的明确答案.我注意到集合使用地图,但为什么不总是使用地图或总是使用集合.而是提供了两个非常相似的容器.提前致谢.