【问题标题】:C++ - std::vector initialisation in constructorC++ - 构造函数中的 std::vector 初始化
【发布时间】:2020-05-05 01:29:44
【问题描述】:

在我学习 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 显然可以挽救这种情况。我不明白为什么。

【问题讨论】:

标签: c++ oop vector constructor initialization


【解决方案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);

使用count 默认插入的T 实例构造容器。没有复制。

vector(size_type count, const T&amp; value);

使用具有value 值的元素的count 副本构造容器。

对于T = unsigned int,“默认插入的实例”就是0u

【讨论】:

  • 好的,我想这基本上就是我想要的。非常感谢。
猜你喜欢
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 2020-10-28
  • 2014-09-07
  • 2020-09-03
  • 2016-05-03
  • 1970-01-01
相关资源
最近更新 更多