Jak skopiować vector zmieniając typ na wskaźnik

0

std::vector<Obiekt> obiekty;

std::vector<Obiekt*> wskazniki = obiekty; // ????!?! Kopia samych adresów a nie obiektów!

Chcę żeby wskaźniki skopiował obiekty ale nie jako wartosci tylko wskazniki do obiektów trzymanych w obiekty a nie same obiekty jako wartosci. Jak to ugryźć?

0

Potrzebuje skopiować wskaźniki żeby na chwilę posortować wartości nie zmieniając kolejnosci oryginalnego kontenera. Klasa Obiekt jest kosztowna do skopiowania. Może jest jakiś inny sposób?

0
for(std::size_t i = 0; i < wskazniki.size(); ++i){
    wskazniki[i] = &obiekty[i];
}

Może jakoś tak?

Swoją drogą to ryzykowne. Zmiana w rozmiarze obiekty może spowodować, że wskaźniki się pogubią.
Poza tym jaki sens w tym jest, można użyć referencji do wektora.

 
2
for (size_t i = 0; i < obiekty.size(); ++i)
    wskazniki.push_back(&obiekty[i]);

o to chodzi?

4

Będąc bardzo czepliwym, powinno się używać raczej std::addressof przyjmując bardzo generyczne założenia. Co jeśli obiekt będzie miał przeładowany operator &?
http://en.cppreference.com/w/cpp/memory/addressof

1

A nie chodzi o to?

#include <iostream>
#include <vector>
using namespace std;

class obj{
    int a;
};
vector <obj> vObject;
vector <obj*> vWskObject;

int main()
{
    for(auto &object : vObject)
     vWskObject.push_back(&object);
}  
4
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
#include <iterator>
using namespace std;

int main() {
	struct foo { int x; };
	
	vector<foo> foos = 
		{ {1}, {2}, {3} };
		
	vector<foo *> foo_ptrs;
	foo_ptrs.reserve(foos.size());
	
	transform(
		begin(foos), end(foos), 
		back_inserter(foo_ptrs), 
		addressof<foo>);
		
	return 0;
}
0
Biały Mleczarz napisał(a):

std::vector<Obiekt> obiekty;

std::vector<Obiekt*> wskazniki = obiekty; // ????!?! Kopia samych adresów a nie obiektów!

Chcę żeby wskaźniki skopiował obiekty ale nie jako wartosci tylko wskazniki do obiektów trzymanych w obiekty a nie same obiekty jako wartosci. Jak to ugryźć?

A co to za pajacowanie?

Robisz sortowany jakiś ten kolektor, i po wskaźnikach a nie wprost.
Wtedy samo się posortuje... wedle zadanego operatora do porównywania: >.

0

@spartanPAGE a może być takie sortowanie? Dobrze to jest wykonane?

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Obj{
    public:
        Obj(int val);
        int GetValue();
    private:
        int value;
};
Obj::Obj(int val){
    value = val;
}
int Obj::GetValue(){
    return value;
}

vector <Obj*> SortVector(vector <Obj> &vObj){
    vector <Obj*> vPtr;
    for(auto &ptr : vObj)
     vPtr.push_back(&ptr);
    sort(vPtr.begin(), vPtr.end(), [](Obj *ptr1, Obj *ptr2)->bool{return ptr1->GetValue() < ptr2->GetValue();});
    return vPtr;
}

int main()
{
    vector <Obj> myVect;
    myVect.push_back(10);
    myVect.push_back(23);
    myVect.push_back(4);
    myVect.push_back(18);
    myVect.push_back(82);

    vector <Obj*> myPtr = SortVector(myVect);
    for(auto &p : myPtr)
     cout << p->GetValue() << " ";
    return 0;
}
 
2

@gswidwa działanie kodu jest prawidłowe, natomiast możnaby się wielu rzeczy przyczepić.

  1. Dlaczego Obj nie jest PODem?
  2. Po co ten private int i getter, skoro i tak on nic nie robi? Gettery są okej, ale wtedy, kiedy faktycznie są potrzebne, np są czymś w rodzaju wrappera dostępu - wykonują przy okazji dodatkowe akcje, logowanie chociażby. Tak naprawde żadna klasa nie jest Ci potrzebna przecież.
  3. Powinieneś przyjmować parametr jako const. Immutable obiekty są bardzo fajne.
  4. for (auto &&ptr : vObj) (@kq się nie zgadza z tym, jednak moim zdaniem warto preferować bardziej generyczne rozwiązania)
  5. Preferowałbym jednak sposób podany przez @spartanPAGE. Jak dla mnie o wiele bardziej przejrzysty.
  6. std::addressof. Patrz posty wyżej.
1
std::vector<Obiekt> obiekty;
… … …
std::vector<Obiekt*> wskazniki(obiekty.size(), NULL);
std::transform(obiekty.begin(), obiekty.end(), wskazniki.begin(), [](const Obiekt&x){ return &x; });

1 użytkowników online, w tym zalogowanych: 0, gości: 1