C++ - std::vector 在构造函数中初始化
C++ - std::vector initialisation in constructor
在我学习 C++ 的过程中,我很难理解在此特定设置中初始化向量的最佳实践:
struct Data {
vector<int> vec;
Data(const int k) {
for (int i = 0; i < k; i++) vec.push_back(0);
}
};
因此在主函数中我只声明 Data mydata(10);
和 mydata
将具有 k=10
个元素的属性向量 mydata.vec
。
但是,我真的觉得效率低下,必须设置一个for循环并逐个元素填充mydata.vec
,所以在网上查找我发现了其他方法,老实说我不明白。无论如何,我试图用
替换给定的构造函数
Data(const int k) {
vec.resize(k);
}
和
Data(const int k) : vec(k,0) {}
关于已删除的已修改对象的错误消息或运行时发生的分段错误。您能否解释一下在这种框架中初始化向量的最 C++ 风格或最有效的方法?考虑到出于某种原因,我对什么是初始化列表几乎一无所知。
编辑:
在这里,我提出了一个直接取自我的代码的最小示例:
#include <iostream>
#include <vector>
using namespace std;
struct Data {
vector<unsigned int> mydata, count;
Data(const unsigned int k) {
for (unsigned int i = 0; i < 2 * k; i++) {
mydata.push_back(i + 1);
//count.push_back(0); // HERE 1
}
count.resize(k); // HERE 2
}
void update_stats(const unsigned int p) { count[mydata[0] - 1] += 1; }
};
void twist(Data& stuff, const unsigned int m) {
unsigned int temp;
for (unsigned int i = m; i < 2 * m; i++) {
temp = stuff.mydata[i];
stuff.mydata.erase(stuff.mydata.begin() + i);
stuff.mydata.insert(stuff.mydata.begin() + (i - m) * 2, temp);
}
stuff.update_stats(m);
}
int main() {
unsigned int p, k = 200;
Data stuff(k);
for (p = 1; p <= k; p++) twist(stuff, p);
for (p = k; p >= 1; p--) twist(stuff, p);
cout << stuff.count[stuff.mydata[0] - 1] << endl;
return 0;
}
很抱歉没有在进一步减少方面做得更好。此代码会产生分段错误。但是,注释 HERE 2
行并使用 HERE 1
显然可以挽救这种情况。我不明白为什么。
for
循环后
for (unsigned int i = 0; i < 2 * k; i++)
count.push_back(0);
count
向量将包含 2k
个零。但是在 count.resize(k)
之后它将只包含 k
个零。
固定构造函数可能如下所示:
Data(const unsigned int k) : mydata(2 * k), count(2 * k, 0) {
std::iota(mydata.begin(), mydata.end(), 1u);
}
要给mydata
分配顺序递增的序列,可以使用std::iota
算法。 , 0
可以在不改变行为的情况下删除,但您可能希望明确初始值。
这两个constructors的语义很简单:
explicit vector(size_type count);
Constructs the container with count
default-inserted instances of T
. No copies are made.
vector(size_type count, const T& value);
Constructs the container with count
copies of elements with value value
.
对于T = unsigned int
,“默认插入的实例”只是0u
。
在我学习 C++ 的过程中,我很难理解在此特定设置中初始化向量的最佳实践:
struct Data {
vector<int> vec;
Data(const int k) {
for (int i = 0; i < k; i++) vec.push_back(0);
}
};
因此在主函数中我只声明 Data mydata(10);
和 mydata
将具有 k=10
个元素的属性向量 mydata.vec
。
但是,我真的觉得效率低下,必须设置一个for循环并逐个元素填充mydata.vec
,所以在网上查找我发现了其他方法,老实说我不明白。无论如何,我试图用
Data(const int k) {
vec.resize(k);
}
和
Data(const int k) : vec(k,0) {}
关于已删除的已修改对象的错误消息或运行时发生的分段错误。您能否解释一下在这种框架中初始化向量的最 C++ 风格或最有效的方法?考虑到出于某种原因,我对什么是初始化列表几乎一无所知。
编辑: 在这里,我提出了一个直接取自我的代码的最小示例:
#include <iostream>
#include <vector>
using namespace std;
struct Data {
vector<unsigned int> mydata, count;
Data(const unsigned int k) {
for (unsigned int i = 0; i < 2 * k; i++) {
mydata.push_back(i + 1);
//count.push_back(0); // HERE 1
}
count.resize(k); // HERE 2
}
void update_stats(const unsigned int p) { count[mydata[0] - 1] += 1; }
};
void twist(Data& stuff, const unsigned int m) {
unsigned int temp;
for (unsigned int i = m; i < 2 * m; i++) {
temp = stuff.mydata[i];
stuff.mydata.erase(stuff.mydata.begin() + i);
stuff.mydata.insert(stuff.mydata.begin() + (i - m) * 2, temp);
}
stuff.update_stats(m);
}
int main() {
unsigned int p, k = 200;
Data stuff(k);
for (p = 1; p <= k; p++) twist(stuff, p);
for (p = k; p >= 1; p--) twist(stuff, p);
cout << stuff.count[stuff.mydata[0] - 1] << endl;
return 0;
}
很抱歉没有在进一步减少方面做得更好。此代码会产生分段错误。但是,注释 HERE 2
行并使用 HERE 1
显然可以挽救这种情况。我不明白为什么。
for
循环后
for (unsigned int i = 0; i < 2 * k; i++)
count.push_back(0);
count
向量将包含 2k
个零。但是在 count.resize(k)
之后它将只包含 k
个零。
固定构造函数可能如下所示:
Data(const unsigned int k) : mydata(2 * k), count(2 * k, 0) {
std::iota(mydata.begin(), mydata.end(), 1u);
}
要给mydata
分配顺序递增的序列,可以使用std::iota
算法。 , 0
可以在不改变行为的情况下删除,但您可能希望明确初始值。
这两个constructors的语义很简单:
explicit vector(size_type count);
Constructs the container with
count
default-inserted instances ofT
. No copies are made.
vector(size_type count, const T& value);
Constructs the container with
count
copies of elements with valuevalue
.
对于T = unsigned int
,“默认插入的实例”只是0u
。