我们有
std::vector <std::vector <unsigned short int>> face;
face.resize(nElm);
Run Code Online (Sandbox Code Playgroud)
它可以resize()用于第一维.但是,我也想reserve()记住脸上的元素; 我的意思是第二个维度.(我知道之间的差异resize()和reserve())
以下代码不能用gcc 4.7.0编译(使用std = c ++ 11 -O3)
int n;
std::vector< int[4] > A;
A.resize(n);
Run Code Online (Sandbox Code Playgroud)
错误消息是长度,但最终
functional cast to array type ‘_ValueType {aka int[4]}‘
Run Code Online (Sandbox Code Playgroud)
它是否正确?还是应该编译?更重要的是,如何避免这个问题?(没有定义一个新的结构来保存int[4])
编辑:
如何用C++ 98解决问题?
我有一个非常大的向量(每个数百万条,每条1024字节).我超过了向量的最大大小(得到一个错误的内存分配异常).我正在对项目向量进行递归操作,这需要访问向量中的其他元素.这些操作需要快速完成.我试图避免写入磁盘速度的原因.有没有其他方法来存储不需要写入磁盘的数据?如果我必须将数据写入磁盘,那么最理想的方法是什么>
编辑更多细节.
我在数据集上执行的操作是基于向量中的其他数据点递归生成字符串.读入数据时会对数据进行排序.数据集范围为50,000到50,000,0000.
我有一个存储数组的类,我需要编写一个方法来返回指向该数组的指针,以便其他对象可以访问/修改它.
在我的程序的旧版本中,我通过使用C风格定义数组来实现这一点.即,拥有一个私有元素bool* list,然后在构造函数中分配内存(并在析构函数中释放它).那么方法非常简单:
bool* MyClass::getList() {
return list;
}
Run Code Online (Sandbox Code Playgroud)
现在,我决定重写代码并使用std::vector<bool>而不是经典数组.问题是我还修改了上面的方法:
bool* MyClass::getList() {
return &(list[0]);
}
Run Code Online (Sandbox Code Playgroud)
这似乎是将C++向量转换为C数组的标准方法.但是,我无法编译我的代码,我收到以下错误:
error: taking address of temporary [-fpermissive]
error: cannot convert ‘std::vector<bool>::reference* {aka std::_Bit_reference*}’ to ‘bool*’ in return
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮我解决这个问题并告诉我该怎么办?
(我还读过另一个选择是使用list.data()指针,但这只适用于最新版本的C++编译器.我不确定这是不是一个好主意).
谢谢,
我已经围绕长寿命向量的共同主题编写了无数的软件模块,有时(在未指定的频率下)必须更新其内容.
惯用法实施:
void LongLived::reconfigure(const InputT& whatever_input)
{
m_vector.clear();
m_vector.reserve(whatever_input.size());
populate(m_vector, whatever_input);
}
Run Code Online (Sandbox Code Playgroud)
请注意,惯用实现永远不会减少其内部缓冲区的容量.如果这不好怎么办?只是用shrink_to_fit(),我想:
void LongLived::reconfigure(const InputT& whatever_input)
{
m_vector.clear();
m_vector.reserve(whatever_input.size());
m_vector.shrink_to_fit(whatever_input.size()); // ? Here
populate(m_vector, whatever_input);
}
Run Code Online (Sandbox Code Playgroud)
哦,那将是多么美好......但令我惊讶的是,它没有编译,因为shrink_to_fit()不需要一个数字!
shrink_to_fit()应该使用的方式显然是先填充向量.然后,你调用shrink_to_fit(),这将从事后的向量中的元素数量中获得容量需求,但如果我事先已经告诉它,那显然是次优的,因为现在,所有内容都必须被移动.
目标:我想vector_reserve_or_shrink()在这种情况下使用一个函数:
void LongLived::reconfigure(const InputT& whatever_input)
{
m_vector.clear();
vector_reserve_or_shrink(m_vector, whatever_input.size()); // ? Implement this!
populate(m_vector, whatever_input);
}
Run Code Online (Sandbox Code Playgroud)
我实际上并不痴迷于从矢量中删除每个未使用的字节.更确切地说,我很乐意将其留给某些实现定义,例如shrink_to_fit(),可能知道分配器的怪癖,并可能选择什么都不做.通过这种方式,人们不会冒险进行抽象反转,从而否定任何较低级别的优化.例如,假设分配器的粒度是16:那么,当你要求一个时,矢量实现可能会免费给你15个字节,据我所知,这对于尝试回馈只会适得其反.
我有一个任务来分析vector当Node(一个由long值组成的对象)被添加到它之前的行为方式.我已经在a的复制构造函数中放置了一个计数器,Node以查看当向量移动到新位置时(即vector增长时)调用它的次数.
我得到以下结果:
Windows - MinGW编译器:
|--------------------Vector-------------------|
Size Time Creates Copies Destroys
100 0 ms 100 411 411
Run Code Online (Sandbox Code Playgroud)
Linux的:
|--------------------Vector-------------------|
Size Time Creates Copies Destroys
100 0 ms 100 227 227
Run Code Online (Sandbox Code Playgroud)
Node.cpp
Node::Node(const Node& x){
this->value = x.get_value();
copy_count++;
}
Run Code Online (Sandbox Code Playgroud)
SortedVector.cpp
vector<Node> data;
void SortedVector::prepend(const long value){
const Node x(value);
data.insert(data.begin(), x);
}
Run Code Online (Sandbox Code Playgroud)
令人宽慰的是复制构造函数的计数与析构函数中的相同,但是,请您帮助我理解Linux和Windows中输出的差异吗?
在C++代码的开头,我初始化一个1000000(百万)bool类型数据的向量.但是,在valgrind中,最大堆+堆栈使用量显示为200Kb.鉴于Bool是1字节,不应该是1 Mb?
有没有我没有意识到的优化?或者我错过了什么?
谢谢你的提前.
我使用的是Ubuntu64 16.04系统.编译没有-O参数的代码.
编辑:代码可以简化为此,
vector<bool> * isPrime;
int main(){
isPrime = new vector<bool>(1000000, true);
}
Run Code Online (Sandbox Code Playgroud)
编辑2:似乎有一个我没有意识到的优化(在评论中说明).谢谢.
如果我尝试访问std::vector越界,将导致未定义的行为.
const std::vector<int> vec {1,2,3};
const int a = vec[4];
Run Code Online (Sandbox Code Playgroud)
然而,这段代码可能不会立即失败,但a会有一个任意值;
如果vec通过该方法访问,.at()则将抛出异常.
const int a = vec.at(4);
Run Code Online (Sandbox Code Playgroud)
缺点是,如果.at()总是使用,性能将显着下降.
我的问题是,如果某些C++编译器支持编译标志,则会切换operator []到该.at()方法.
将其打开可以获得良好的可调试代码.将其关闭会导致快速发布可执行文件.
我知道堆检查工具,比如valgrind会发现这些bug,但是它们需要花费很多时间.
如果我有类似的东西:
vector<int> longVector = { ... };
vector<int> newVector;
transform(longVector.begin(), longVector.end(), back_inserter(newVector),
[] (int i) { return i * i; });
Run Code Online (Sandbox Code Playgroud)
STL是否能够newVector在处理和添加新元素之前预先分配空间?我知道这不是算法的要求,但是"好的"实现能够优化吗?或者,对于这种情况,我newVector.reserve(longVector.size());之前应该更喜欢添加吗?我不一定要问每个stdlib实现是否存在(尽管如果有人知道特定的例子会很好),但考虑到算法的接口和要求,更多是否可能(和预期).
这个问题适用于多个STL算法transform,copy,move,fill_n,...而且不只是back_inserter,也front_inserter和inserter我想.
编辑:为了清楚起见,我的意思是一个STDLIB是否能够提供的具体实现中,例如,transform,对于情况下,当输出迭代是back_inserter的vector,在这种情况下,将访问向量的对象并保留足够的空间来存储该distance在实际运行转换之前,在给定的迭代器对之间.
I'd like to have a templated function taking in a vector<T> v and a function op, mapping T to vector<U> and would like to concatenate the results of applying f to every element vector of v to return a vector<U> = [ Elements of op(v[0]), Elements of op(v[1]) ...].
A working option I found was adding an example in the function to allow for template deduction:
template <typename Container>
Container& concat(Container& c1, Container const& c2) {
c1.insert(end(c1), begin(c2), end(c2));
return …Run Code Online (Sandbox Code Playgroud)