2016-09-11 11 views
5

Próbuję zastosować transformację do shared_ptr i zapisać do shared_ptr, jednocześnie korzystając z funkcji w klasie.C++ 11 transformacja z shared_ptr do wektora i klasy

Stworzyłem ten przykład:

#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; 
} 

Jak widać here To powoduje zrzut segmentacji. Jakąkolwiek pomoc, w jaki sposób mogę rozwiązać ten problem, aby uzyskać dane wyjściowe o wartości {2, 4, 6, }?

Zauważ, że używam lambda, ponieważ potrzebuję go w mojej pełnej implementacji.

Próbowałem też wymienić,

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

z

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

Odpowiedz

4
shared_ptr<vector<int> > result(new vector<int>()); 

skonstruować nowy, pusty wektor.

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

Od result jest pusta, result->begin() zwraca końcową wartość iteratora. std::transform kopiuje sekwencję wejściową, stosuje transformację lambda i zapisuje przekształcony wynik w iteratorze wyjściowym.

Ponieważ wektor jest pusty, nie ma do czego pisać. Kończysz koniec pustej tablicy, powodując niezdefiniowane zachowanie i uszkodzenie pamięci.

W tym przypadku, po prostu przydzielenia macierz wyjściową, ponieważ wiesz, co jej wielkość powinna być z góry:

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

Teraz to stworzy tablicę wyjściową odpowiednim rozmiarze, begin() zwróci iterator na początek tablicy, a std::transform() będzie szczęśliwie przechwytywać na tablicy.

Jeśli naprawdę chcą uniknąć dodatkowego obciążania wartości inicjalizacji nową tablicę, tak aby został on zastąpiony, można użyć reserve() do przydzielenia ostateczny rozmiar tablicy, a następnie użyć std::back_insert_iterator dla iteratora wyjściowego, zamiast przemijania w begin().

+0

Dzięki! To działa. Użyłem 'reserve' oraz' back_inserter() '. Rozwiązanie można znaleźć [tutaj] (http://coliru.stacked-crooked.com/a/188945e985a51137). – Stereo

Powiązane problemy