Zgodnie z odpowiedzią Bradgonesurfing wiele razy nie trzeba tak naprawdę łączyć dwóch wektorów (O (n)), ale po prostu pracować z nimi tak, jakby były one połączone (O (1)) . Jeśli tak jest w twoim przypadku, można to zrobić bez potrzeby bibliotek Boost.
Sztuką jest utworzenie wektorowego proxy: klasy opakowania, która manipuluje odwołaniami do obu wektorów, zewnętrznie postrzeganych jako pojedynczy, ciągły.
STOSOWANIE
std::vector<int> A{ 1, 2, 3, 4, 5};
std::vector<int> B{ 10, 20, 30 };
VecProxy<int> AB(A, B); // ----> O(1). No copies performed.
for (size_t i = 0; i < AB.size(); ++i)
std::cout << AB[i] << " "; // 1 2 3 4 5 10 20 30
REALIZACJA
template <class T>
class VecProxy {
private:
std::vector<T>& v1, v2;
public:
VecProxy(std::vector<T>& ref1, std::vector<T>& ref2) : v1(ref1), v2(ref2) {}
const T& operator[](const size_t& i) const;
const size_t size() const;
};
template <class T>
const T& VecProxy<T>::operator[](const size_t& i) const{
return (i < v1.size()) ? v1[i] : v2[i - v1.size()];
};
template <class T>
const size_t VecProxy<T>::size() const { return v1.size() + v2.size(); };
GŁÓWNE KORZYŚCI
Jest O (1) (czas stały), aby go utworzyć, przy minimalnym przydziale dodatkowej pamięci.
NIEKTÓRZY RZECZY DO ROZWAŻENIA
- Powinieneś to zrobić tylko wtedy, gdy naprawdę wiesz, co robisz, zajmując się referencjami . To rozwiązanie jest przeznaczone do konkretnego celu postawionego pytania, dla którego działa całkiem dobrze . Zastosowanie go w innym kontekście może prowadzić do nieoczekiwanego zachowania, jeśli nie masz pewności, jak działają odwołania.
- W tym przykładzie AB nie zapewnia operatora non-const access ([]). Uwzględnij go, ale pamiętaj: ponieważ AB zawiera referencje, przypisanie mu wartości wpłynie również na oryginalne elementy w A i / lub B. Niezależnie od tego, czy jest to pożądana cecha, należy zadać pytanie dotyczące aplikacji dokładnie zastanów się.
- Wszelkie zmiany dokonane bezpośrednio w A lub B (takie jak przypisywanie wartości, sortowanie itp.) Również „modyfikują” AB. Niekoniecznie jest to złe (w rzeczywistości może być bardzo przydatne: AB nigdy nie musi być wyraźnie aktualizowana, aby zachować synchronizację z A i B), ale z pewnością jest to zachowanie, o którym należy pamiętać. Ważny wyjątek: zmiana rozmiaru A i / lub B na coś większego może spowodować, że zostaną one ponownie przydzielone w pamięci (ze względu na potrzebę ciągłego miejsca), a to z kolei unieważni AB.
- Ponieważ każdy dostęp do elementu jest poprzedzony testem (mianowicie „i <v1.size ()”), czas dostępu VecProxy, chociaż stały, jest również nieco wolniejszy niż w przypadku wektorów.
- To podejście można uogólnić na n wektorów. Nie próbowałem, ale to nie powinna być wielka sprawa.