【问题标题】:C++11 transform with shared_ptr to a vector and class使用 shared_ptr 将 C++11 转换为向量和类
【发布时间】:2017-01-18 20:07:36
【问题描述】:

我正在尝试将转换应用于 shared_ptr 并存储到 shared_ptr,同时还在类中使用函数。

我创建了这个例子:

#include <vector>
#include <iostream>
#include <memory>
#include <algorithm>

using namespace std;

class MyClass {
public:
    int factor = 0;
    MyClass(const int factor_) : factor(factor_) {}

    shared_ptr<vector<int> > mult(shared_ptr<vector<int> > numbers) {
        shared_ptr<vector<int> > result(new vector<int>() );

        transform(numbers->begin(), numbers->end(), result->begin(),
            [this](int x){ return factor * x; });

        return result;
    }
};

int main()
{
    shared_ptr<vector<int> > numbers(new vector<int>());
    shared_ptr<vector<int> > res(new vector<int>());
    MyClass times_two(2);

    numbers->push_back(1);
    numbers->push_back(2);
    numbers->push_back(3);

    res = times_two.mult(numbers);

    cout << "{";
    for (unsigned int i = 0; i < res->size(); ++i)
        cout << res->at(i) << ", ";
    cout << "}";    

    return 0;
}

正如here 所见,这会导致分段转储。关于如何解决这个问题以便输出产生{2, 4, 6, }的任何帮助?

请注意,我使用 lambda 是因为在我的完整实现中需要它。

我也试过替换,

transform(numbers->begin(), numbers->end(), result->begin(),
        [this](int x){ return factor * x; });

transform((*numbers).begin(), (*numbers).end(), (*result).begin(),
        [this](int x){ return factor * x; });

【问题讨论】:

    标签: c++ c++11 lambda transform shared-ptr


    【解决方案1】:
        shared_ptr<vector<int> > result(new vector<int>() );
    

    你构造了一个新的空向量。

        transform(numbers->begin(), numbers->end(), result->begin(),
            [this](int x){ return factor * x; });
    

    由于result 为空,result-&gt;begin() 返回结束迭代器值。 std::transform 复制输入序列,应用转换 lambda,并将转换后的结果写入输出迭代器。

    由于向量为空,因此没有可写入的内容。您正在运行超出空数组的末尾,导致未定义的行为和内存损坏。

    在这种情况下,只需预先分配输出数组,因为您提前知道它的大小:

    shared_ptr<vector<int> > result(new vector<int>(numbers->size()) );
    

    现在,这将创建正确大小的输出数组,begin() 将返回一个迭代器到数组的开头,std::transform() 将愉快地在数组上涂鸦。

    如果你真的希望避免值初始化新数组的额外开销,只是为了让它被覆盖,你可以使用reserve()预分配数组的最终大小,然后使用std::back_insert_iterator作为输出迭代器,而不是传入begin()

    【讨论】:

    • 谢谢!这样可行。我使用了reserveback_inserter()。解决方法可以在here找到。
    猜你喜欢
    • 2017-05-01
    • 2018-07-16
    • 2021-06-21
    • 1970-01-01
    • 2015-06-15
    • 2014-04-15
    • 2016-10-19
    • 2010-11-24
    • 2015-10-06
    相关资源
    最近更新 更多