[C++] Rzutowanie vectorów

0

Witam.
Ostatnio starałem się rzutować jeden typ vectora na inny. Program działa, ale ciekawi mnie czy taki sposób jest bezpieczny i przenośny. Z góry dziękuje za pomoc.

#include <cstdio>
#include <vector>

using std::vector;

int main()
{
	vector<int> tak(5, 0x12345678);
	vector<char> inaczej = reinterpret_cast<vector<char>& >(tak);
	
	for (int i = 0; i < inaczej.size(); i++)
		printf("%02X ", inaczej[i]);
		
	return 0;
}
0

Oj coś mis się wydaję, że tym razem to miałeś szczęście, że zadziałało.
Na pewno bezpiecznie można kastować pomiędzy wektorami wskaźników na różne typy (na tyle na ile ten ty pozwala).

0

hm.. zakladajac ze nie trafi przypadkiem na jakas dzika specjalizacje std::vector, to wszystkie one powinny miec ten sam uklad pol w obiekcie vector, wiec defacto po chamskim przerzutowaniu jedyne co to kompilator zobaczy inny typ elementu vector'a..

ale - jak powiedzialem - z takim zalozeniem. a 100% pewnosci nie masz. najlepiej dodaj gdzies asserta sizeof(vector<A>) == sizeof(vector< B>), to Ci da minimum pewnosci ze kompilator nie wtracil do tej konkretnej klasy zadnego alignu. ale przed wredna specjalizacja dajaca taki sam rozmiar to to Cie nie uchroni..</b>

0

Z dzikich specjalizacji vectora standard przewiduje tylko std::vector<bool>. Tylko o ten typ powinienem się teoretycznie martwić.
Co do rozłożenia w pamięci dobrze mówisz. Pogrzebałem na szybkiego w szablonach i wychodzi, że wszystkie kontenery używają std::allocator do zarządzania pamięcią. Problem pojawia się tylko z rzutowaniem z mniejszego typu do większego. Trzeba tylko wyrównać pamięć do nowego rozmiaru co nie jest już dużym kłopotem.
Ogólnie wielkie dzięki za pomoc.

0

wewnatrz (~dynamicznej) tablicy 'zarzadzanej' przez alokator -- to to juz raczej oczywiste ze przesuniecia elementow trzeba recznie poprawic. nie mialem na mysli ulozenia w pamieci elementow, tylko pol vectora! dlatego mowie o specjalizacjach i align'ie. jesli jakims trafem, po zmianie alokatora/typuelementu/specjalizacji na niestadardowa, okaze sie ze wewnetrzne POLA vectora sa przesuniete, bo komus w specjalizacji sie zachcialo dorzucic jakies dwa pola na poczatek vectora (por. tez align skladowych struktury/klasy..) to do elementow sie wcale nie dostaniesz bo ... po przerzutowaniu wewnetrzny wskaznik na dyn-tablice bedzie smieciem. tylko dlatego wspominam o owym banalnym assercie. czyniac voodoo, lepiej zachowywac sie defensywnie

0

Niebezpieczny zabieg a już na pewno nieczytelny (nikt by się takiego nie spodziewał). Odradzam, zwłaszcza że można zrobić to "normalnie" na tysiąc innych sposobów, np:

        vector<int> tak(5, 0x12345678);
        char* inaczej = reinterpret_cast<char*>(&tak.front());
        for (int i = 0, end = tak.size() * sizeof(int) / sizeof(char); i < end; i++)
                printf("%02X ", inaczej[i]);
0

nie no, oczywiscie, z ta drobna roznica, ze typ wynikowy juz nie bedzie vector<x> tylko x*.. nie zebym ow zabieg popieral ;)

btw. autorze: na dobra sprawe, po co trzymac sie rzutowania na vector<x>? chyba tylko po to, by moc uzywac jego metod.. wiec poza sprawdzeniem wielkosci obiektu specjalizowanego vectora i jego ukladu w pamieci ....masz tez do przejrzenia kod wszystkich metod vectora, zeby sprawdzic czy po przerzutowaniu na chama na pewno beda wciaz poprawne ;)

0
quetzalcoatl napisał(a)

btw. autorze: na dobra sprawe, po co trzymac sie rzutowania na vector<x>? chyba tylko po to, by moc uzywac jego metod..
Właśnie odradzam. Nie opłaca się. Każdą z metod można zastąpić "normalnym" sposobem. Ciut więcej roboty, ale korzyści o wiele większe. Ja dałem akurat przykład do iteracji.

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