C++ 将2d向量值设置为0的快速方法

C++ 将2d向量值设置为0的快速方法,c++,vector,C++,Vector,给出下面的例子 #include <iostream> #include <vector> #include <algorithm> #include<iterator> using namespace std; template<typename T> ostream& operator<<(ostream& os, const vector<T>& v){ copy(v.b

给出下面的例子

#include <iostream>
#include <vector>
#include <algorithm>
#include<iterator>

using namespace std;

template<typename T>
ostream& operator<<(ostream& os, const vector<T>& v){
    copy(v.begin(), v.end(), ostream_iterator<T>(os, "  "));
    return os;
}


int main (){

vector<int>vec;
vector<vector<int>> x(10,vector<int>());
for(int i=0; i< x.size(); i++)
    x[i].resize((rand() % 100 + 1), 10);

for(int i=0; i< x.size(); i++)
    fill(x[i].begin(),x[i].end(),0);

return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
样板

ostream&operator在您的示例中,最初用零初始化向量最简单、最快。在父向量的构造函数中,如果它们的长度相同,或者在调整大小中,如果向量的长度是随机的

如果您有一个包含旧值的向量的现有向量,并且希望将它们全部设置为零,那么
memset
通常是最快的方法。由于vector保证有连续的存储,并且您的内部vector不包含复杂(非POD)对象,因此使用
memset

for(auto& v : x)
    std::memset(&v[0], 0, sizeof(v[0]) * v.size());

也就是说,
std::fill\n
std::fill
可能同样快,并且不限于POD/内置对象,而且更易于阅读,因此我建议改用它。如果您遇到瓶颈,请对代码进行基准测试,并查看在目标平台上使用
memset
是否有任何收获。否则,请坚持现有的方法。

在您的示例中,最初用零初始化向量是最简单、最快的方法。在父向量的构造函数中,如果它们的长度相同,或者在调整大小中,如果向量的长度是随机的

如果您有一个包含旧值的向量的现有向量,并且希望将它们全部设置为零,那么
memset
通常是最快的方法。由于vector保证有连续的存储,并且您的内部vector不包含复杂(非POD)对象,因此使用
memset

for(auto& v : x)
    std::memset(&v[0], 0, sizeof(v[0]) * v.size());
也就是说,
std::fill\n
std::fill
可能同样快,并且不限于POD/内置对象,而且更易于阅读,因此我建议改用它。如果您遇到瓶颈,请对代码进行基准测试,并查看在目标平台上使用
memset
是否有任何收获。否则,请坚持现有的方法。

使用接受初始值的vector::vector(count,value)构造函数。在以下情况下,它将被设置为零

vector< vector<int> > yourVector(value1, vector<int>(value2)); 

// initial value will be zero
vectoryourVector(值1,向量(值2));
//初始值将为零
使用接受初始值的vector::vector(count,value)构造函数。在以下情况下,它将被设置为零

vector< vector<int> > yourVector(value1, vector<int>(value2)); 

// initial value will be zero
vectoryourVector(值1,向量(值2));
//初始值将为零
在C++11中

for (auto &i : x)
    std::fill(i.begin(), i.end(), 0);
或(在C++11之前)

for(std::vector::iterator i=x.begin(),end=x.end();i!=end;++i)
std::fill(i.begin(),i.end(),0);
将很难击败-并且可能会使用索引击败循环(如C++11中的
x[i]

for (auto &i : x)
    std::fill(i.begin(), i.end(), 0);
或(在C++11之前)

for(std::vector::iterator i=x.begin(),end=x.end();i!=end;++i)
std::fill(i.begin(),i.end(),0);

将很难击败-并且可能会使用索引击败循环(如
x[i]
)。

完全没有必要用零填充内部
std::vector
s,因为
resize
default会在向量中插入新元素,而value会初始化它们。在
int
s的情况下,值初始化意味着将它们设置为0


从标准中确定这一点可能有点困难,因此这里是线索(来自N4296-C++14草案):

根据
调整大小的定义:

如果
size()

默认插入的
定义

如果通过计算表达式初始化
X
元素,则默认插入该元素

allocator_traits<A>::construct(m, p)
效果:调用
a.construct(p,std::forward(args)…)
如果调用格式正确;否则,[…]

根据分配器的定义:

效果:构造一个对象 C型在C

默认值:
::新建((void*)c)c(转发(args)…。

根据
新表达式的定义:

  • 如果省略了新的初始值设定项,[…]

  • 否则,新的初始值设定项将根据8.5的初始化规则进行解释,以进行直接初始化

根据直接初始化的定义:

  • [……]

  • 如果初始值设定项为(),则对象的值已初始化

  • [……]

值初始化:

  • 如果T是带有[…]的(可能是cv限定的)类类型
  • 如果T是带有[…]的(可能是cv限定的)类类型
  • 如果T是数组类型,则[…]
  • 否则,对象初始化为零
零初始化:

  • 如果T是标量类型(3.9),则将对象初始化为通过将整数文本0(零)转换为T获得的值

  • 如果[…]


完全没有必要用零填充内部
std::vector
s,因为
resize
default会将新元素插入到向量中,而value会初始化这些元素。在
int
s的情况下,值初始化意味着将它们设置为0


从标准中确定这一点可能有点困难,因此这里是线索(来自N4296-C++14草案):

根据
调整大小的定义:

如果
size()

默认插入的
定义

如果通过计算表达式初始化
X
元素,则默认插入该元素

allocator_traits<A>::construct(m, p)
效果:调用
a.construct(p,std::forward(args)…)
如果调用格式正确;否则,[…]

根据分配器的定义:

效果:构造一个对象 C型在C

默认值:
::新建((void*)c)c(转发(args)…。

根据
新的定义